为什么没有分配给变量的默认值,这些变量尚未在具有main函数的Class中初始化???
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;
}
答案 0 :(得分:5)
请注意,问题中的代码代表不同的情况。在第一种情况下,变量是 local 并存在于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。
答案 1 :(得分:2)
基本原因是,为了捕获常见的程序员错误,Java作者决定确保在使用之前分配每个变量。但是,无法对字段强制执行此操作,因此必须为字段指定默认值。
如果在初始化之前在构造函数中使用字段,则会出现错误,但编译器无法阻止此操作:
class C {
int f;
C() {
init();
}
void init() {
System.out.println(f);
}
}
答案 2 :(得分:1)
在赋值之前读取变量的值是错误的常见来源。在使用变量之前强制你分配一个值会使程序更安全:你会知道你会得到你期望的值而不是一些默认值只是因为你没有预料到某个程序流。
不幸的是,实现此需求的活动性分析只能对局部变量进行,并且您可以在程序使用值初始化之前访问实例字段。为了避免不可预测的行为,JVM将实例字段初始化为默认值。
答案 3 :(得分:1)
当JVM创建新对象实例时,它必须为属性分配内存,因为它们是类本身的一部分。仅仅存在Java原语int需要分配4个字节的内存,而Integer
可以设置为null
,因为它是一个对象。这就是为什么类必须在初始化时将其属性设置为某些东西。