2013-07-25 2 views
1

Почему значения по умолчанию не назначены для переменных, которые не были инициализированы в классе с главной функцией ???Значения по умолчанию - Java Clarification

class Test { 
    public static void main(String[] args) { 

     int x;// x has no default value 
     String y;// y has no default value 
     System.out.println("x is " +); 
     System.out.println("y is " +); 
    } 
} 

Принимая во внимание, что значения по умолчанию присваиваются, если переменные остаются неинициализированными в классе без какой-либо основной функции.

class Student { 
    String name; // name has default value null 
    int age; // age has default value 0 
    boolean isScienceMajor; // isScienceMajor has default value false 
    char gender; // c has default value '\u0000' 
    int x; 
    String y; 
} 
+2

Вы неправильно понимаете ситуацию. Дело не в том, что у одного класса есть основная функция, а у другого нет. Это то, что в первом примере переменные объявляются * внутри * функции (они являются локальными переменными), а во втором они объявляются * вне * функции на уровне класса (это * поля * или * переменные-члены *). –

ответ

5

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

В Java только атрибуты автоматически инициализируются значениями по умолчанию. Во всех методах, даже в методе main(), вы должны явно указать значение инициализации для переменных, объявленных локально внутри метода.

Это объясняется в спецификации языка Java, раздел §4.12.5:

Каждая переменная класса, переменная экземпляра, или компонент массива инициализируется значением по умолчанию при его создании (§15.9, §15.10)

Каждый параметр метода (§8.4.1) инициализируется соответствующим значением аргумента, предоставленной вызвавшего метода (§15.12)

Каждый параметр конструктора (§8.8.1) инициализируется соответствующим значением аргумента предоставлена ​​выражение создания экземпляра класса (§15.9) или явный вызов конструктора (§8.8.7)

параметр исключения (§14.20) инициализируются брошенным объект, представляющего исключение (§11.3, §14.18)

Локальная переменная (§14.4, §14.14) должна быть явно задана значением до ее использования посредством либо инициализации (§14.4), либо назначения (§15.26) способом, который может быть проверен с использованием правил для определенного присвоения (§16)

Чтобы увидеть несколько причин, почему локальные переменные не инициализируются автоматически, взгляните на это предыдущее question.

2

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

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

class C { 
    int f; 

    C() { 
    init(); 
    } 

    void init() { 
    System.out.println(f); 
    } 
} 
1

Чтение значения переменной перед он получил значение, является общим источником ошибок. Заставляя вас назначать значение перед использованием переменной, делает программы более безопасными: вы узнаете, что получите ожидаемое значение, а не какое-то значение по умолчанию, потому что вы не ожидали определенного потока программы.

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

1

Когда JVM создает экземпляр нового объекта, он должен выделять память для атрибутов, потому что они являются частью самого класса. Для простого существования Java-примитива int требуется выделить 4 байта памяти, тогда как Integer может быть установлен в null, так как это объект. Вот почему классы должны иметь свои атрибуты для чего-то инициализироваться.

+0

", в то время как целое число может быть установлено в null, поскольку это объект?" Не могли бы вы прояснить эту часть? Вы говорите, что тип данных Integer является объектом? – RDPD

+0

Да. Существует класс java.lang.Integer, который является оберткой объекта для стандартного int. –

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