2014-09-04 2 views
-1

Этого код компилирует (с помощью Java 8), что дает предупреждение The assignment to variable value has no effect:Java инициализация статического поля к себе

package test; 

public class Test { 
    private static int value; 

    static { 
     value = Test.value; 
    } 

    public static void main(String[] args) { 
     System.out.println(value); 
    } 
} 

Программа выводит 0, как и ожидался. Но почему компилятор разрешает это, каков прецедент?

+0

Ну, это предупреждает вас, что в любом случае это бессмысленно, я думаю, было бы навязчивым не позволять кому-то писать что-то очевидное, это не влияет на поток ваша программа, так почему вы ожидаете ошибку компиляции? – theMarceloR

+0

есть прецедент для этого, см. Мой ответ ниже ... – CodeFanatic

+0

@ Андрю Мосс приятно, что вы принимаете ответ, который не отвечает на ваш вопрос, что такое прецедент ... – CodeFanatic

ответ

2

Поскольку переменные в Java имеют значение по умолчанию, которое инициализируется до любой другой инициализации, если инициализация не происходит непосредственно при объявлении переменной. Действительно value - 0.

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

+0

и что такое usecase? – CodeFanatic

+3

@FelixLahmer: тот же пример использования 'if (true)'. Правильный код (с точки зрения компилятора) не означает полезный код. Если 'if (true)' вызывает ошибку тоже? – Jack

+0

Достаточно честный. Он выглядит более странным, если вы объявляете и инициализируете поле в той же строке. С помощью статического инициализатора немного яснее, что происходит. –

1

Если в качестве переменной присваивается самому себе, компилятор выдает предупреждение, как в следующем примере:

int x = 2; 

    x = x; 

Это предупреждение, как правило, является признаком проблемы программирования, поэтому для себя это хорошая вещь, имейте это, но в случае, если переменная является летучей, которая будет ONLIEST Полезно Использовать случай Я могу подумать, предупреждение неверно.

int y = 0; 
    volatile int x = 2; 
    y = 3; 
    x = x; 

Модель модели Java обеспечивает, чтобы каждый поток, считывающий x и y в этом порядке, гарантированно видел значение 3 для y. Это связано с тем, что при назначении x в одном потоке и чтении x в другом устанавливается порядок до-заказа.

Назначение не влияет на значение переменной, но оно имеет огромный эффект для параллелизма.

Обратите внимание, что в приведенном выше примере предупреждения может быть подавлены с помощью

x = x + 0; 

Но там нет такого хака для ссылок. Один случай использования, который поразит вас, заключается в попытке синхронизировать содержимое int[]. Один поток считывает элемент:

myarray[3] 

и другой поток записывает элемент:

myarray[3] = 2; 

Поскольку члены массива themselfes не могут быть неустойчивыми, вы должны сделать myarray энергозависимой и добавьте следующие строки в поток записи:

myarrray = myarray;