默认值-Java澄清
为什么没有将默认值分配给变量,而这些变量在具有main函数的类中没有初始化默认值-Java澄清,java,Java,为什么没有将默认值分配给变量,而这些变量在具有main函数的类中没有初始化 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
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;
}
请注意,问题中的代码代表不同的情况。在第一种情况下,变量是局部变量,存在于
main()
方法中。在第二种情况下,您声明的是实例属性,而不是局部变量
在Java中,只有属性会自动初始化为默认值。在所有方法中,即使在main()
方法中,也必须显式地为方法内部本地声明的变量提供初始化值
Java语言规范第节对此进行了解释:
每个类变量、实例变量或数组组件在创建时都会使用默认值进行初始化(§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)进行验证
要了解局部变量未自动初始化的几个原因,请查看前面的内容。请注意,问题中的代码表示不同的情况。在第一种情况下,变量是局部变量,存在于
main()
方法中。在第二种情况下,您声明的是实例属性,而不是局部变量
在Java中,只有属性会自动初始化为默认值。在所有方法中,即使在main()
方法中,也必须显式地为方法内部本地声明的变量提供初始化值
Java语言规范第节对此进行了解释:
每个类变量、实例变量或数组组件在创建时都会使用默认值进行初始化(§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)进行验证
要了解局部变量没有自动初始化的几个原因,请看一下前面的内容。基本原因是,为了捕捉常见的程序员错误,Java作者决定确保在使用每个变量之前对其进行赋值。但是,无法对字段强制执行此操作,因此他们必须为字段指定默认值 如果在构造函数初始化之前使用该字段,则会出现错误,但编译器无法防止:
class C {
int f;
C() {
init();
}
void init() {
System.out.println(f);
}
}
基本原因是,为了捕捉常见的程序员错误,Java作者决定确保每个变量在使用前都已赋值。但是,无法对字段强制执行此操作,因此他们必须为字段指定默认值 如果在构造函数初始化之前使用该字段,则会出现错误,但编译器无法防止:
class C {
int f;
C() {
init();
}
void init() {
System.out.println(f);
}
}
在给变量赋值之前读取变量的值是常见的错误源。强制您在使用变量之前分配一个值会使程序更安全:您将知道您将获得预期的值,而不是某些默认值,因为您没有预期某个程序流
不幸的是,实现这种需求的活动性分析只能对局部变量进行,并且您可以在程序使用值初始化实例字段之前访问它们。为了避免不可预测的行为,JVM将实例字段初始化为默认值。在给变量赋值之前读取变量的值是常见的错误源。强制您在使用变量之前分配一个值会使程序更安全:您将知道您将获得预期的值,而不是某些默认值,因为您没有预期某个程序流
不幸的是,实现这种需求的活动性分析只能对局部变量进行,并且您可以在程序使用值初始化实例字段之前访问它们。为了避免不可预测的行为,JVM将实例字段初始化为默认值。当JVM创建新的对象实例时,它必须为属性分配内存,因为它们是类本身的一部分。仅仅存在Java原语int就需要分配4个字节的内存,而
Integer
可以设置为null
,因为它是一个对象。这就是类在初始化时必须将其属性设置为某个对象的原因。当JVM创建新的对象实例时,它必须为属性分配内存,因为它们是类本身的一部分。仅Java原语int的存在就需要分配4字节的内存,