Java 实例变量初始化方法
Java instance variables initialization with method
我对下面这段代码有点困惑:
public class Test{
int x = giveH();
int h = 29;
public int giveH(){
return h;
}
public static void main(String args[])
{
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
这里的输出是0 29
,但是我想这一定是编译错误,因为在方法giveH()
的时候变量h应该还没有初始化。那么,编译是从上到下逐行进行的吗?为什么这是有效的?为什么 x
的值是 0 而不是 29?
Java 中的编译不需要在使用前声明方法。 Java tutorial 更详细地介绍了初始化。
这里有一个思考的方法:编译器会记下在范围内某处寻找名为 giveH 的方法,只有当它离开范围并且找不到它时才会出错。一旦到达 giveH 声明,便条便已解决,大家都很高兴。
此外,Java中实例变量的变量初始化被移动到构造函数的开头。你可以认为上面的行被分成两部分,上面的 x 和 h 的声明,以及构造函数中的赋值。
声明的顺序在这种情况下很重要。当变量 x 被初始化时,h 的 default value 为 0,因此 giveH() 将 return 该默认值。之后,变量h被赋值为29.
您还可以查看 Field Initialization and Forward References During Field Initialization 上的 Java 语言规范部分。
int
的默认值为 0
(参见 here)。因为您在 h
之前初始化 x
,giveH
将 return 为 int 的默认值(例如 0)。
如果你这样调换顺序
int h = 29;
int x = giveH();
输出将是
29 29
@Maloubobola 给出了正确的答案,但由于您似乎还没有完全理解,所以让我尝试详细说明。
创建Test时,它会运行一次变量初始化(x = giveH(), h= 29)。你的误解可能是变量 x 总是由 giveH() 决定的,而它只在 x 初始化时决定它的值。
这就是为什么语句的顺序在这里很重要; x 在 h 之前初始化,因此在 x 初始化时调用 giveH() 时 h 为 0。
如果我们不在这个程序中初始化像 x 这样的非静态变量的值,JVM 将为 class 级别的非静态变量提供默认值零。
在字段初始值设定项中使用方法是不好的做法。您可以通过将 h 设置为 final 来解决此问题。然后它将在加载 class 时初始化。
import java.util.ArrayList;
public class Test {
int x = giveH();
final int h=29;
final public int giveH(){
return h;
}
public static void main(String args[]) {
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
一旦声明,所有数组元素都会存储它们的默认值。
存储对象的数组中的元素默认为空。
存储原始数据类型的数组元素存储:
0 表示整数类型(byte、short、int、long);
0.0 用于十进制类型(浮点型和双精度型);
布尔值是假的;
\u0000 用于字符数据。
Actauls 值只有在我们给它们初始化时才会出现
我对下面这段代码有点困惑:
public class Test{
int x = giveH();
int h = 29;
public int giveH(){
return h;
}
public static void main(String args[])
{
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
这里的输出是0 29
,但是我想这一定是编译错误,因为在方法giveH()
的时候变量h应该还没有初始化。那么,编译是从上到下逐行进行的吗?为什么这是有效的?为什么 x
的值是 0 而不是 29?
Java 中的编译不需要在使用前声明方法。 Java tutorial 更详细地介绍了初始化。
这里有一个思考的方法:编译器会记下在范围内某处寻找名为 giveH 的方法,只有当它离开范围并且找不到它时才会出错。一旦到达 giveH 声明,便条便已解决,大家都很高兴。
此外,Java中实例变量的变量初始化被移动到构造函数的开头。你可以认为上面的行被分成两部分,上面的 x 和 h 的声明,以及构造函数中的赋值。
声明的顺序在这种情况下很重要。当变量 x 被初始化时,h 的 default value 为 0,因此 giveH() 将 return 该默认值。之后,变量h被赋值为29.
您还可以查看 Field Initialization and Forward References During Field Initialization 上的 Java 语言规范部分。
int
的默认值为 0
(参见 here)。因为您在 h
之前初始化 x
,giveH
将 return 为 int 的默认值(例如 0)。
如果你这样调换顺序
int h = 29;
int x = giveH();
输出将是
29 29
@Maloubobola 给出了正确的答案,但由于您似乎还没有完全理解,所以让我尝试详细说明。
创建Test时,它会运行一次变量初始化(x = giveH(), h= 29)。你的误解可能是变量 x 总是由 giveH() 决定的,而它只在 x 初始化时决定它的值。
这就是为什么语句的顺序在这里很重要; x 在 h 之前初始化,因此在 x 初始化时调用 giveH() 时 h 为 0。
如果我们不在这个程序中初始化像 x 这样的非静态变量的值,JVM 将为 class 级别的非静态变量提供默认值零。
在字段初始值设定项中使用方法是不好的做法。您可以通过将 h 设置为 final 来解决此问题。然后它将在加载 class 时初始化。
import java.util.ArrayList;
public class Test {
int x = giveH();
final int h=29;
final public int giveH(){
return h;
}
public static void main(String args[]) {
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
一旦声明,所有数组元素都会存储它们的默认值。 存储对象的数组中的元素默认为空。 存储原始数据类型的数组元素存储: 0 表示整数类型(byte、short、int、long); 0.0 用于十进制类型(浮点型和双精度型); 布尔值是假的; \u0000 用于字符数据。
Actauls 值只有在我们给它们初始化时才会出现