我尝试运行此程序,但这会产生运行时错误(StackOverflowError)。如果在类Static中我将引用对象ob,static,则不会发生错误。任何人都可以解释一下为什么会发生这种情况并请解释我如何初始化字段变量(无论是静态还是非静态以及引用或非引用变量)?
public class Static {
public Static ob = new Static();
private int a;
public void win(Static obj) {
//System.out.printf("ob.a = %d\n", ob.a);
obj.a = 15;
System.out.printf("ob.a = %d", ob.a);
}
}
public class StaticTest {
public static void main(String args[])
{
Static obj=new Static();
//Static obj1=new Static();
// obj.win(obj1.ob);
}
}
答案 0 :(得分:5)
每次实例化Static
类的对象(非常混乱的名称BTW)时,您创建一个Static
对象并实例化它,它创建另一个Static
对象并实例化它所以...(所以你得到一个StackOverflow错误):
public Static ob = new Static();
答案 1 :(得分:2)
您的代码创建了一个Static类的实例。 创建实例时,会初始化其属性。您的代码所做的是通过指向新的Static实例初始化'ob'属性。 然后创建静态类的新实例,并且......你有一个“无限初始化循环”。
如果将“static”keyworkd附加到正在创建“类属性”的属性,即在该类的所有实例之间共享的属性。 这意味着当您执行代码并且静态的第一个实例是要创建的go时,JAva会初始化ob属性。静态的后续实例不会初始化它,因为它在所有实例之间共享。
请参阅此示例:http://www.roseindia.net/java/beginners/staticvariable.shtml
答案 2 :(得分:1)
static
个字段。这就是为什么将类型更改为static
会使其无法递归。
当字段不是static
时,你会创建一个无限递归,导致堆栈溢出;当你实例化对象时,它实例化另一个,实例化另一个,依此类推。
答案 3 :(得分:1)
静态在类级别 ,因此首次在内存中加载类时会初始化它。此外,静态块按照声明的顺序是init。
相反,类变量(非静态)是每个对象,并且当创建该类的对象时 init ,而不是以任何特定的顺序,我相信。
在你的情况下,如果你没有使ob
静态,它将尝试初始化静态类对象,当尝试使用ob时,它再次创建另一个静态(因为它调用新的静态())并且这一直持续到你用完堆栈(StackoverFlow)。
如果你使ob
为静态,那么这只是init一次(当静态类加载到内存中时)你就可以了。
答案 4 :(得分:0)
如果创建字段的实例级别,则会导致永无止境的递归,最终会导致StackOverFlow内存错误。
另一方面,如果将字段定义为 static ,则避免递归,因为静态字段变量属于Class,而不属于对象实例。 JVM中的类只创建一次而不是Object实例,后者可能很多。