2017-06-17 31 views
-2
class ABC { 
    int x; 
    static ABC y = new ABC(); 
} 


public class XYZ { 

    public static void main(String[] args) { 
     ABC q = new ABC(); 
     q.x = 5; 
     System.out.println(q.x); 
    } 

} 

有人可以解释代码运行时发生的一切(一步一步)吗?拥有自己类型的静态成员的类

此外,当static关键字被删除之前,实例y,StackOverflow发生错误。为什么在static关键字存在时不会发生这种情况?

在此先感谢。

+0

是你的家庭作业,你不明白这个代码准确吗? –

+2

如果你删除了'static',那么每个'ABC'实例都有它自己的'y'字段,这意味着对于每个创建的ABC实例,''y'值需要一个新的'ABC'实例,所以它会创建一个新的'ABC'实例,它需要一个新的'y'值,因此它会创建一个新的'ABC'实例,它需要一个新的'y'值,因此它会创建一个新的ABC实例,新的'y'值,所以它创建一个新的ABC实例,它需要一个新的'y'值,所以它创建一个新的ABC实例,它需要一个新的'y'值,StackOverflowError! – Andreas

+1

这就像试图不正确地使用SingleTon模式:p – WilomGfx

回答

1

static表示变量的单个实例在多个引用对象中使用(在本例中为y)。

A static该字段位于class的上下文中,这意味着该类的所有实例都将指向相同的static对象实例。 在一个场景:

ABC a = new ABC(); 
ABC b = new ABC(); 
System.out.println(a.y==b.y); 

打印将导致true,因为y两个ab指向同一个对象实例。

非静态字段会填充继承自己的单个实例;这意味着在一个情形:

ABC a = new ABC(); 
ABC b = new ABC(); 
System.out.println(a.y==b.y); 

(在一个假设的情况,其中,例如将不会触发的StackOverflow)将导致false,因为a.y相同实例作为b.y;每个人在其y字段中都有自己的独立实例ABC

因为当ABC实例化时,需要另一个ABC实例是y场,其中,实例化时,创建另一个ABC,依此类推,无限(直到堆栈溢出)一个StackOverflow会发生不static关键字。

随着static,ABC的一个静态实例,让我们把它创建sABC,以及它自己的y场只是引用它本身,所以实例化的无限循环不会发生。

+0

感谢您的帮助。你能告诉我,对象'q'看起来会是什么样子。我的意思是它有对象'y'或只有整数'x'? –

+0

“ABC”的所有实例都有一个“y”字段。不同之处在于'y'对象指向的内容。在'q'(你在你的main中创建的实例)中,它指向'y'(一个静态的,第二个实例,它在实例化时被实例化,因为'static ABC y = new ABC();'定义ABC类是什么。)...在'y'(实例)中,'y'(字段)指向'y'(实例)本身。如果'y'不是静态的,'y'实例会用一个新的实例填充它的'y'字段,这需要另一个实例来存放它自己的内部'y'字段,这需要一个用于它的'y'字段,所以在... – XenoRo

+0

@AayushTaneja我编辑了答案,试图让事情更清晰。如果您仍然不明白,我强烈建议(重新)阅读OOP的基础知识。 – XenoRo

0

当类加载器加载此类时,它将立即创建该类的一个实例并将其分配给类变量y。这是因为y被声明为静态的。 如果你没有声明y静态,那么你认为ABC类的每个实例都有一个属性y,它也是一个ABC。然后你也会说y属性必须分配一个ABC类的新实例,所以无论何时显式创建一个ABC实例,都会为您创建该实例,就像您在main()中的第一个语句中那样。你发现递归?这导致堆栈溢出。

+0

谢谢你的帮助。 –

0

静态变量是一个类级变量。

实例变量是对象级变量。

如果删除static关键字 - 此类尝试实例化自身并发生无尽循环,而静态变量一次创建一个实例并在所有对象之间共享。

堆栈内存保留局部变量和函数调用,所以它溢出了,因为你有无尽的呼叫。

+0

感谢您的帮助。 –

0

的演练

ABC q = new ABC(); 

创建一个名为q

q.x = 5; 

设置q的财产xABC类的新实例5

System.out.println(q.x); 

小学nt下通过q的属性x保持的值(应为5)

静态

static关键字意味着一个类共享同一个变量的每个实例。当您创建类ABC的实例时,它将包含另一个ABC实例作为变量y。当您创建另一个ABC实例时,它也有一个变量y,但该变量与ABC的第一个实例持有的y相同。

如果您要删除static关键字,则y将不会由ABC的每个实例共享。当您创建ABC的实例时,它将创建它自己的y,并且该y将创建它自己的y,依此类推,直到您用完内存并且发生StackOverflow错误。

+0

谢谢你的帮助。 –