2013-12-08 6 views
9

Существует два класса, каждый из которых имеет собственное статическое поле. Что произойдет, когда одно поле зависит от другого? Например:Статические переменные Java, которые зависят друг от друга

public class A { 
    public final static Something something = new Something(B.needed); 
} 

public class B { 
    public final static Needed needed = new Needed(); 
} 

Тест я сделал предположить, что в этом случае needed будет инициализирован перед something. В тесте я просил Java для переменной класса A, а B не был загружен раньше. Однако результатом может быть просто совпадение. Есть ли какой-либо механизм в Java, который гарантирует мне, что needed всегда будет инициализироваться для использования в качестве аргумента?

I другой тест. Результаты также показывают, что в крайних случаях конечных примитивные типов имеют по умолчанию значения (так что они на самом деле имеют разные значения в разных местах коды, несмотря на заключительном):

public class A { 
    public final static int test = 3 - B.test; 
} 

public class B { 
    public final static int test = 2 - A.test; 
} 

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

A.test = 1 
B.test = 2 

Затем, если вы запустите тест с B нагрузки во-первых, значения будут:

A.test = 3 
B.test = -1 

кажется, что J ava просто использует значение по умолчанию int значение 0. Я был удивлен, что этот код компилируется.

Результаты второго теста также показывают, что Java пытается инициализировать статическое поле, которое оно планирует использовать при инициализации переменной из другого класса. Это верно? Является ли это документированным, предсказуемым поведением?

+0

См. Http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4.2 для большого количества подробностей –

+0

Возможный дубликат [Что делать, если статический инициализатор в класс X вызывает метод в Y, но статические инициализаторы Y вызывают метод в X для установки его статических значений?] (http://stackoverflow.com/questions/13971407/what-if-a-static-initializer-in- class-x-invokes-a-method-in-y-but-ys-static-in) – Henry

+0

Будьте осторожны - такие зависимости когда-то приводят к потерям в ремонтопригодности. –

ответ

4

До тех пор, пока у вас есть древовидные зависимости ваших классов, вы можете полагаться на класс X, который был инициализирован, когда ему нужен класс Y. Как только вы вводите циклы (для класса X нужны Y и Y, нужно X или даже A потребности B, для которых требуется C, для которого требуется D, который нуждается в A), поведение не определено и может изменяться всякий раз, когда вы меняете версию Java, поставщика JVM, аппаратного обеспечения платформу или что-то еще. Не делайте этого - круговые зависимости почти всегда являются результатом плохого планирования.

Смежные вопросы