2013-10-24 86 views
1

我的工作和Inner Class概念和編寫下面code_的Java:的StackOverflowError

public class InnerClassConcepts { 
private int x = 11; 

public static void main(String... args) { 
    // method local 'x' variable 
    int x = new InnerClassConcepts().new InnerA().new InnerB().x; 

    InnerClassConcepts in = new InnerClassConcepts(); 
    InnerA InnerA = in.new InnerA(); 
    InnerA.InnerB xx = in.new InnerA().new InnerB(); 

    System.out.println("InnerClassConcepts`s x = " + in.x); 
    System.out.println("InnerB`s x = " + xx.x); 
    System.out.println("main`s x(local variable) = " + x); 
    // System.out.println("InnerA`s x = " + InnerA.x); 
    System.out.println("InnerA`s y = " + InnerA.y); 
} 

/** 
* Local inner class. 
*/ 
class InnerA { 
    int y = 10; 

    /* 
    * java.lang.StackOverflowError coming over here... I don`t 
    * understand why? 
    */ 
    // int x=new InnerClassConcepts().new InnerA().new InnerB().x;//Line-29 
    /** 
    * Inner class inside an another Inner class. 
    */ 
    class InnerB { 
     private int x = 22; 
     int z = InnerA.this.y; 

    } 

} 
} 

Output_

InnerClassConcepts's x = 11 
InnerB's x = 22 
main's x(local variable) = 22 
InnerA's y = 10 

我很奇怪,爲什麼StackOverflowErrorline-29到來時,我去掉線29 。在main方法中工作的地方。

有人可以幫助我,我錯了什麼或背後有什麼概念?

+0

通過方式,這給你一個機會**學習如何讀取堆棧跟蹤**。 – Ingo

回答

5

讓我們的例子簡單一點,解釋發生了什麼:

class Example { 
    private Example example = new Example(); 
} 

會發生什麼事,當你創建一個新的Example對象?

新對象被創建,然後它的成員變量被初始化。類Example有一個成員變量Example。因此,要初始化成員變量,會創建一個新的Example對象。那個人又有一個類型爲Example的成員變量需要被初始化。所以,再次創建一個新的Example對象。而且這個人還有一個需要初始化的Example成員變量。這一直持續下去。

你有一個無限的遞歸循環,這導致StackOverflowError

你在你的類具有完全一樣的東西InnerA當你取消註釋行29:成員變量x初始化爲新InnerA,它具有與新InnerA初始化自己的成員變量等

+1

這聽起來像昨天,誰想知道爲什麼類String嵌入一個字符數組而不是一個字符串^^ – Julien

-2

內部類應該是靜態的。或者您是否需要每個實例的新類聲明?

看到這個答案來解釋爲什麼:whats-the-advantage-of-making-an-inner-class-as-static-with-java

另請參閱該FindBugs的錯誤描述:finbugs: inner class should be static

如果你想使你的內部類的靜態,你可以看到,它不編譯你寫的方式。

+0

它在哪裏說它們應該是靜態的?非靜態嵌套類被定義爲內部類。請在發佈「答案」之前進行調查。 –

+0

@WimOmbelets很多人都這麼說。甚至有一個findbugs規則。看到這個線程:[作爲一個內部類的靜態與java的優勢](http://stackoverflow.com/questions/16147405/whats-the-advantage-of-將靜態內部類與java一起使用) – mwhs

+1

渲染靜態類的一個可能的優勢與OP意味着它應該是靜態的有明顯的區別。無論哪種方式,您的答案都無法解決手頭的問題。 –

5

InnerA一個實例被創建可變x被初始化這引起InnerA被創建和另一x被初始化等。

因此StackOverflowError

// int x=new InnerClassConcepts().new InnerA().new InnerB().x;//Line-29 

StackoverFlowError,你應該看到的InnerA構造函數中一次又一次地被調用的堆棧跟蹤。

像這樣的事情

at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31) 
at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31) 
at InnerClassConcepts$InnerA.<init>(InnerClassConcepts.java:31) 
0

int x = new InnerClassConcepts().new InnerA().new InnerB().x; 

,每次執行創建的InnerA一個新實例的時間。由於該行創建的InnerA它會一次又一次地被稱爲另一個實例..

0

您希望通過創建一個新的InnerA實例初始化InnerA的成員x。因此,這將永遠不會結束:)