2013-12-11 53 views
1

請忽略我的傲慢......學習java這幾天,我碰到這個完全一樣的問題,我的問題:Why can't I instantiate and create Object without main method? (Stack Overflow Error)

期待一個可能downvote呢......但請經過我的問題一次! !我試圖
爲什麼我不能在java外部實例化任何方法?

代碼:

public class Arrayprg{ 

    Arrayprg ag = new Arrayprg(); //ignore this for a while and go thru code please  

    public static void main(String []args){ 
     System.out.println("Hello Array"); 
     new Arrayprg().declarearray(); 
    } 


    public void declarearray() 
    { 
     int[] arr; 
     arr = new int[11]; 
     new Arrayprg().assignarr(arr); 
    } 


    public void assignarr(int arr[]) 
    { 
     int i; 
     for(i = 0; i < 11; i++) 
     { 
      arr[i] = i; 
     } 
     new Arrayprg().printarr(arr); 
    } 

    public void printarr(int arr[]) 
    { 
     int i; 
     for(i = 0; i < 11; i++) 
     { 
      System.out.println(arr[i]); 
     } 
    } 
} 

思考邏輯,要通過代碼,你會看到很多new arrayprg() ....我以爲是instantiate outside of methods,並呼籲通過所有方法它之後,但我想這是不允許在Java中。

請告訴我造成我的問題

在引述問題的解決去,因爲它解釋說,下面的事情發生了:

Create new instance of Arrayprg 
     -> ag = Create new instance of Arrayprg 
      -> ag = Create new instance of Arrayprg 
      -> ag = Create new instance of Arrayprg 

說明在這個問題
給出....每當類的實例被實例化時,它就被初始化。這將永遠不會終止,直到你內存不足並導致堆棧溢出。使用調試器運行它以獲得更清晰的視圖。

我的問題 ,所以我有我的方案,這是創建一個循環的每次我創建一個實例,但爲什麼當我通過new Arrayprg().

調用函數我的意思是這個叫Arrayprg ag = new Arrayprg();是當我打電話通過new Arrayprg()裏面的方法爲什麼Arrayprg ag = new Arrayprg();得到調用,並創建了錯誤的循環Stackoverflow ?????

+1

下面的答案都描述你的計算器。然而,爲了更好地理解「對象」,我認爲你應該閱讀關於對象是什麼以及方法如何對對象的內部數據進行操作的教程。我認爲[本Oracle/Sun Java教程](http://docs.oracle.com/javase/tutorial/java/javaOO/objectcreation.html)中的'Rectangle'類應該指導您朝着正確的方向發展(另請參閱在[tutorialspoint]上的'Puppy'示例(http://www.tutorialspoint.com/java/java_jject_classes.htm)。也許還可以閱讀關於對象上下文中「this」的含義。 – wmorrison365

回答

1

解決方案:

改變這一行:

Arrayprg = new Arrayprg(); //ignore this for a while and go thru code please  

到:

static Arrayprg a = new Arrayprg(); 

而且您將不再讓你無限遞歸問題,因爲現在它只會創建它的一個實例在所有實例之間共享 - 而不是每個實例立即創建一個新實例。

作爲在Java中構建Object的所有成員變量初始化,初始值設定代碼塊等的部分都稱爲以及構造本身。

因此,爲了創建一個新的Arrayprg,它所做的一件事就是查找需要初始化和初始化它們的成員變量。

在這種情況下,它會找到Arrayprg a = new Arrayprg();,因此爲了初始化該字段a,它會嘗試創建一個新的Arrayprg()

但是,新Arrayprg()經歷完全相同的過程中又一次,又一次,又一次等

有許多的方式來解決這個問題 - 包括:

  1. 在通Arrayprg作爲構造函數的一個參數 - 所以不需要創建一個新的。
  2. 充分利用Arrayprg靜態 - 所以只能一個一個需要創建一次,而不是創建一個新的
  3. 懶惰initaliziation在Arrayprg每一次,所以你只創建它的第一次嘗試,並訪問它,而不是當父Arrayprg創建時。

爲什麼不能在方法調用中發生:

引起遞歸這裏是呼叫創建一個新的對象的過程中發生的最重要的事情。如果試圖創建一個新對象涉及到創建同一個對象的另一個副本,那麼最終會導致無限遞歸,然後導致失敗。

所以你可以在你喜歡的任何地方創建一個新對象 - 只要它不在創建它自己的範圍內。

class A { 
    A a = new A(); // Recursion 
} 

class A { 
    A() { 
     A a = new A(); // Recursion 
    } 
} 

class A { 
    A getNewA() { 
     return new A(); 
     // This is fine as it doesn't happen during creation of an A 
    } 
} 

class A { 
    A() { 
     getNewA(); 
     // Recursion as calling getNewA creates a new A, which calls getNewA, which.... 
    } 

    A getNewA() { 
     return new A(); 
     // This is fine on its own but is broken if called from the constructor 
    } 
} 

class B { 
    A a = new A(); 
    // This is fine as B is not A, so you can create a new A within B. 
} 
+0

我想它會停止堆棧溢出,但他的代碼不會更好,認爲他需要了解'this'是什麼。 – wmorrison365

+0

@ wmorrison365:不僅'this',我需要了解它的很多東西。這個代碼只是一個練習!:) – NoobEditor

1

您創建的Arrayprg一個實例時,都會調用這一行:Arrayprg = new Arrayprg();,這意味着每次創建一個時間,它創建了另一個,另一個,另一個等你可以有實例化對象,但實例相同的另一個目的鍵入會導致無限循環。另外,在你的方法(declareArr,assignArr等)中,你可以刪除'new Arrayprg()'。只需調用現有對象上的函數。

5

This will cause a StackOverflowError。

你告訴我們忽略的一條線,有趣的是,罪魁禍首。當你實例化一個新的Arrayprg然後調用任何對象初始值設定項,包括new Arrayprg()然後遞歸地嘗試保持調用構造函數沒有結束。刪除該行,或將其放入靜態初始化程序中。更好的是,不要在主要方法之外創建Arrayprg,因爲您的Arrayprg不需要Arrayprg本身的實例,

我會更清楚,但我不知道您要實現的目標。

+0

最後一個愚蠢的問題....當我調用'Arrayprg = new Arrayprg();'時,它創建SOF並且控制永遠不會使用任何使用'new Arrayprg()'的方法,因此它們沒有連接到任何位置? – NoobEditor

1

讓我們一起來看看。

Arrayprg = new Arrayprg(); 

所以,你有什麼需要創建Arrayprg類型的對象?那麼你需要創建它的領域。

Arrayprg = new Arrayprg(); 

再一次,你告訴JVM給你另一個Arrayprg對象。根據定義,這意味着要製造另一個Arrayprg對象。

這給你一個StackOverflowException

解決方案?

你不應該像這樣嵌套類型。沒有用。你已經在裏面了,所以使用它的方法。

public void declarearray() 
{ 
    int[] arr; 
    arr = new int[11]; 
    assignarr(arr); 
} 

按照這種模式,你將不需要0​​字段。

0

在一個類中你可以在任何方法外創建對象,對象不能是同一個類。

這是沒有意義的。作爲一項規則。

相關問題