2015-03-29 2 views
0
class Person{ 
    public static String name="Mr.zhang"; 
    //public static int age; 
    static{ 
     age=20; 
     System.out.println("initiate age"); 
    } 
    public static int age; 
    public static String address; 
    static{ 
     address="beijing"; 
     age=34; 
    } 
public static void main(String[] args){ 
    System.out.println(name); 
    System.out.println(age); 
    System.out.println(address); 
} 

Я определяю переменную - «возраст» после ее инициализации, и я нахожу, что она работает. Оба из них являются статическими, поэтому почему они не выполняются в соответствии с последовательностью кода.Статический блок и статические переменные в java

+4

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

ответ

2

Есть две вещи, о которых вам нужно подумать.

  1. Порядок инициализации (порядок, в котором значения присваиваются полям)
  2. Область - где в коде может поле от видел

Если я правильно прочитал ваш вопрос, вы, кажется, думаете, что эти две вещи одинаковы, но на Java они отделены друг от друга.

Хотя сама инициализация находится в порядке строк исходного кода, это не относится к области поля. Поле находится в области видимости во всем теле класса, также до его объявления.

(Аналогично для метода (или любого другого типа члена) - вы можете вызвать метод, который был объявлен после точки вызова.)

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

Единственный момент, когда это может сбить с толку, - это когда вы назначаете одновременно с объявлением поля. Как это:

public class Snippet { 
    static { 
     a = 20; 
    } 

    private static int a = 10; 

    static { 
     System.out.println(a); 
    } 

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

Но это не то, что сбивает с толку - просто думать о декларации и задания в виде двух отдельных вещей - декларация в области видимости всего класса, но назначение выполняется в порядке исходного кода. Так private static int a = 10; можно рассматривать как:

private static int a; 
static { 
    a = 10; 
} 

Чтобы дать вам справочную ссылку, все это определено в спецификации языка Java. В частности, это в section 6.3 which defines the scoping rules:

Объем заявления члена m объявленного или унаследованного от типа класса C (§8.1.6) является все тело C, в том числе любых вложенных деклараций типа ,

+0

Большое спасибо. Я пытаюсь понять раздел, но я новый кодер, поэтому я не могу его хорошо понять. Можете ли вы объяснить это проще? – dashenswen

+0

Просто посмотрите ссылку на JLS в качестве дополнительной информации - вам не нужно понимать ее для программирования Java (есть книги, которые объясняют это гораздо более четко), но это полезная информация, когда вы хотите узнать некоторые детали, которые удивляют. Я обновил остальную часть ответа, надеюсь, сделать его более ясным. –

+0

Вы имеете в виду, что определение (то, что вы упоминаете в ответе как инициация) переменной, может быть помещено перед объявлением? Вы знаете, что это может нарушить правило. – dashenswen

1

Блок выполнен в соответствии с порядком кода (ваш возраст будет 34).

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

+0

Я знаю, что весь код, связанный с статическим полем, обрабатывается в начале. Но оба они принадлежат статическому полю. Кто из них должен быть обработан первым? – dashenswen

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