今天遇到一个比较有意思的代码,也不是很难,如下
public class Test {
public static Test t1 = new Test();
{
System.out.println("blockA");
}
static {
System.out.println("blockB");
}
public static void main(String[] args){
Test t2 = new Test();
}
}
这段代码最终的执行效果会是什么呢?有几点需要知道,为什么可以在类的定义中实例化自己?不会递归到底吗?
为什么可以在类的定义中实例化自己而不会编译出错?
答:因为在Test类加载到JVM上,声明属于当前包下,所以编译时,属性虽然有Test类的实例化对象,但是Test类可以找到,所以不会报错。
为什么在方法(例如上面的psvm)中可以实例化对象而不会递归出错?
答:方法是等到被调用时才去执行的、才去new对象的。同理这时可以找到Test类而不会编译出错,而方法中new完后没有其他操作了,里面的对象t2虽然也有此方法,但没有去调用。如果要递归,那应该是要不断用对象去调用此方法才会递归。
为什么属性为类自己的对象时就递归出错了?
class A {
A a = new A();//a为属性
}
...main(...){
A aa = new A();//此时栈溢出
}
答:此时类A有一个属性是a ,而a是A类的,则属性a作为对象,也有一个属性a,所以当类A实例化后,每个属性a都会包含属性a,这样不断递归下去,直到栈溢出。
为什么属性为类自己的对象时,声明为static就不出错了?
答:因为static随着类的加载而加载,是写进方法区的,之后再造对象是共享之前的static属性的,所以就不会再去new对象了。