общедоступная статическая конечная переменная в импортированном классе java

StackOverflow https://stackoverflow.com/questions/1693091

Вопрос

Я случайно наткнулся на Java-код на своем рабочем месте.Вот такой сценарий:Есть 2 класса - ClassA и ClassB.

ClassA внутри него нет ничего, кроме 4 общедоступных статических конечных строковых значений.Его цель состоит в том, чтобы использовать такие значения, как ClassA.variable (не спрашивайте меня почему, это не мой код).

ClassB импорт ClassA.Я отредактировал строковые значения в ClassA и скомпилировал его.Когда я бежал ClassB Я мог видеть, что он использовал старые значения, а не новые.Мне пришлось перекомпилировать ClassB чтобы заставить его использовать новые значения из ClassA!(Мне пришлось перекомпилировать другие классы, которые импортируют ClassA!)

Это только из-за JDK 1.6 или я должен был знать раньше о перекомпиляции ClassB также!Просвети меня.:)

Это было полезно?

Решение

Если значения final переменные из класса ClassA если это константы времени компиляции, компилятор мог бы встроить их в классы, использующие ClassA вместо генерации ссылки во время выполнения.Я думаю, именно это произошло в описанном вами случае.

Пример:

public class Flags {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

public class Consumer {
    public static void main(String[] args) {
         System.out.println(Flags.FOO);
    }
}

В этом примере компилятор, скорее всего, включит значение FOO в код, сгенерированный для Consumer вместо генерации эквивалентной ссылки во время выполнения.Если значение FOO изменения, внесенные позже, вам придется скомпилировать заново Consumer для того, чтобы он использовал новое значение.

Это оптимизация, которая имеет несколько преимуществ в отношении эффективности и скорости скомпилированной программы.Например, встраивание значения может позволить дальнейшую оптимизацию в выражениях, которые его используют, например:

int x = Flags.FOO * 10;

В этом примере встраивание значения (здесь:1) позволяет компилятору заметить, что умножение не имеет никакого значения и может быть опущено все вместе.

Другие советы

Это проблема с двоичной совместимостью.Ссылки на постоянные поля разрешаются во время компиляции.Поведение, которое вы видите, является правильным;если вы измените значения в классе A, то вам придется заново скомпилировать клиент (класс B).Чтобы избежать подобных проблем, рассмотрите возможность добавления констант с использованием типа enum, представленного в Java версии 5.0.

Почему вы пытаетесь скомпилировать классы по отдельности?

Используйте систему сборки, такую как maven или ant, или просто позвольте вашей IDE сделать это.

Единственная безопасная вещь, которую можно сделать, - это перекомпилировать каждую java, которая зависит от класса java, который изменился, до тех пор, пока каждый класс, который мог быть изменен, не будет повторно скомпилирован.

Если вы не используете значения в переключателе, вы можете сделать это вместо этого:

public class A
{
    public static final int FOO;
    public static final String BAR;

    static
    {
        FOO = 42;
        BAR = "Hello, World!";
    }
}

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

Предположим , ClassA выглядит следующим образом:

public class ClassA {
    public static final int FOO = 1;
    public static final int BAR = 2;
}

Если вы перекомпилируете его, ClassB продолжит использовать старые значения.Я предполагаю, что это может зависеть от компилятора, но я думаю, что это типичное поведение.Если вы не хотите перекомпилировать ClassB каждый раз, когда изменяется константа в ClassA, вам придется сделать что-то вроде этого:

public class ClassA {
    public static final int FOO = CONST(1);
    public static final int BAR = CONST(2);

    public static int CONST(int i) { return i; }
}

Потому что теперь javac не желает вставлять константы.Вместо этого он будет вызывать метод CONST(int) при запуске статического инициализатора ClassA.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top