перезагрузить класс, чтобы его статические члены были повторно инициализированы

Предположим, у меня есть такой класс

public class Foo
{
     public static final String FIELD_1 = Env.getProperties("one");
     public static final String FIELD_2 = Env.getProperties("one");

     //....
     public static final String FIELD_N = Env.getProperties("n");
}

Очевидно, все FIELD_* заполняются, когда мы впервые ссылаемся на Foo. Предположим, мой Env.getProperties(String) не является чисто функциональным (т. Е. Он может возвращать разные значения. Каким образом? Здесь не важно)

Как мне заставить класс Foo быть "перезагруженным", чтобы весь код инициализации класса был повторно выполнен (просто чтобы я мог иметь разные значения для статических полей)?

(По разным причинам я не могу сделать эти поля нестатическими или нефинальными. Поэтому, пожалуйста, не предлагайте таких решений, как сделать Foo интерфейсом с различными методами получения, которые должны быть переопределены)

Спасибо


person One Two Three    schedule 16.12.2013    source источник
comment
Моя беда, я не заметил ключевое слово Final. Ответ удален.   -  person Abhinav    schedule 16.12.2013
comment
Если я вас правильно понял, вам нужен снимок какого-то состояния?   -  person Anders Lindén    schedule 16.12.2013
comment
Хм, нет, извините. Я хочу иметь возможность изменять значения этих полей, чтобы вызывающие абоненты могли видеть новые значения.   -  person One Two Three    schedule 16.12.2013
comment
Я думаю, что нам будет легче помочь вам, если мы получим контекст. Мне очень жаль это говорить, но предложения, которые вы получите, не будут статичными. ;)   -  person Anders Lindén    schedule 16.12.2013
comment
Так что, возможно, вы не примете никакого решения.   -  person Anders Lindén    schedule 16.12.2013
comment
Возможный дубликат stackoverflow.com/questions/3971534/   -  person ᴇʟᴇvᴀтᴇ    schedule 16.12.2013


Ответы (1)


Не делай этого!

Возможно, вы сможете сделать это с помощью специального загрузчика классов или JRebel, но это будет огромная проблема. Различные классы могли читать разные значения из этих полей и не синхронизироваться друг с другом и т. Д.

Константы должны быть постоянными. Следуйте принципу наименьшего удивления и произведите рефакторинг для улучшения дизайна.


Предложение минимального рефакторинга

Если поля достаточно хорошо названы - FIELD_1, FIELD_2 и т. Д. - вы можете найти и заменить ссылки на них во всех файлах Java на FIELD_1(), FIELD_2(). Затем напишите код для замены констант статическими методами:

public static String FIELD_1() { return Env.getProperties("one"); }
public static String FIELD_2() { return Env.getProperties("two"); }
//etc.

Это немного некрасиво, но позволит вам попасть туда, куда вы хотите, не прибегая к настоящим хитростям.

person ᴇʟᴇvᴀтᴇ    schedule 16.12.2013
comment
Проблема не в том, что разные вызывающие абоненты получают разные значения (потому что это именно то, что мне нужно). - person One Two Three; 16.12.2013
comment
@aetheria OP может быть просто тем следующим парнем или девушкой, поскольку предыдущий программист решил сделать это таким образом ... - person MxLDevs; 16.12.2013
comment
@OneTwoThree для меня звучит как сомнительный дизайн. Я не знаю, каковы эти различные причины, но если у вас есть возможность улучшить дизайн, не нарушая дюжину приложений, я бы подумал об улучшении дизайна. Плохой дизайн обычно всегда становится проблемой позже, когда его действительно сложно изменить. - person MxLDevs; 16.12.2013
comment
Хорошо, хорошо, я допускаю, что по этим различным причинам этот файл имеет длину более 3000 строк и (столько же полей). И я не в настроении все это переписывать. (И это не считая звонивших) - person One Two Three; 17.12.2013
comment
Я сочувствую тебе! Не могли бы вы написать код, который выполняет рефакторинг файлов Java? т.е. читает в файле Java, изменяет способ доступа к полям и записывает новую версию? По крайней мере, тогда это не ручное усилие. - person ᴇʟᴇvᴀтᴇ; 17.12.2013
comment
Я добавил предложение по рефакторингу. - person ᴇʟᴇvᴀтᴇ; 17.12.2013