2012-10-24 9 views
16
public class TestClass(){ 
    public static void main(String []args) { 
     TestClass t1 = new TestClass(); 
     t1.anything(); 
    } 
} 

同じクラスの定義でオブジェクトを作成するのは奇妙なことではありませんか?そのため、このオブジェクトは新しいオブジェクトを作成するため、この新しいオブジェクトは別のオブジェクトを作成し、無限ループはメモリがいっぱいになるまで終了しません。そのクラスのメソッドの内部でクラスのオブジェクトを作成するのはいいですか?

答えて

13

それは、この新しいオブジェクト は別のものを作るよりも、オブジェクトが新しいオブジェクトを作成し、応答に比べて同じクラス の定義にオブジェクトを作成することが不思議ではないと無限ループがありません

を開始し、メインメソッドは、プログラムを実行するときに一度だけ実行されます。それは再び実行されません。したがって、オブジェクトは1回だけ作成されます。

主な方法をあなたのクラスの外にあると考えてください。あなたのクラスのインスタンスを作成し、作成したインスタンスを使用します。したがって、mainメソッドからインスタンスを作成すると、コンストラクタが呼び出されてインスタンスの状態が初期化され、コンストラクタが返ってくると、mainメソッドの次の文が実行されます。

実際には、メインメソッドはクラスのインスタンスの一部ではないと考えることができます。

しかし、あなたのコンストラクタ(たとえば0-arg)内にクラスのインスタンスを作成し、リファレンスをインスタンス参照変数として作成していれば、無限再帰になります。

public class A { 
    private A obj; 
    public A() { 
     obj = new A(); // This will become recursive creation of object. 
         // Thus resulting in StackOverflow 
    } 
} 
+0

は、すべてのメソッドがクラス定義の外にあることを意味しますか?オブジェクトの作成時にクラス変数のみが作成されますか? –

+0

@RaviKumarMistry。私はそれを言わなかった。主な方法は、事実上、外のクラスとみなすことができます。クラスにはmain以外のメソッドもあります。彼らはあなたのクラスだけにあり、あなたのインスタンス状態の一部です。 –

+0

@RaviKumarMistry。 mainをクラスの中に入れなければならない唯一の理由は、Javaのクラスの外にメソッドを持つことができないことです。 –

1

これは本当に奇妙ではありません。私が知っているすべてのオブジェクト指向言語はこれを可能にします。コードは意味的にオブジェクト定義の一部ですが、実際には任意のオブジェクトの実際の状態とは別のものと見なすことができます。だから、ループはありません。なぜなら、オブジェクト構築はあなたのメソッドを呼び出さないからです(もちろん、そうでなければ問題あります)。

0

newを使用してインスタンス変数を初期化するオブジェクトコンストラクタを呼び出すと、これはスーパークラスのすべてのコンストラクタが呼び出されるまで発生します。あなたは、あなたが以下を実行しようとしました場合にのみ、無限ループ(スタックオーバーフローエラー)を持っているでしょうオブジェクト

4

を作成するたびに実行されますコンストラクタの内部にいくつかのコード置く場合 :

public class TestClass { 
    public TestClass() { 
     TestClass t = new TestClass(); 
    } 
} 

をと別の場所では、クラスTestClassのオブジェクトを作成しようとします。

0

プログラムが起動すると、mainメソッドが実行されます。 Javaでは、クラスの外にメソッドを作成することはできません。すべてのメソッドはクラス内にカプセル化する必要があります。したがって、プログラムへのエントリポイントとしてのメインメソッドは、クラス内になければなりません。このプログラムを実行すると、mainメソッドが一度実行され、内部でコードが実行されます。あなたのケースでは、囲むクラスTestClassのオブジェクトを作成します。これは起こる必要はありません。このクラス以外のオブジェクトも作成できます。あなたは@ adarshrの答えで説明されているように、無限ループしか得られません。

0
public class TestClass{ 
    public static void main(String []args) { 
    TestClass t1 = new TestClass(); 
    t1.anything(); 
    } 
} 

これは完全に有効なコードです。 mainメソッドが呼び出されると、TestClassの以前のインスタンスは存在しません(mainメソッドがstaticであるため、これは不要です)。

public class Test2{ 
    public Test2 clone(){ 
    return new Test2(); 
    } 
} 

これも完全に有効です。 Test2の新しいインスタンスを作成すると、cloneメソッドが含まれていますが、メソッドは自動的に実行されません。 cloneメソッドが呼び出された場合にのみ、Test2のインスタンスがもう1つ作成されます。

public class MyLinkedList{ 
    MyLinkedList next; 
    MyLinkedList(int elems){ 
    if(elems>0){ 
     next = new MyLinkedList(elems-1); 
    }else{ 
     next = null; 
    } 
    } 
} 

は、作成はとても時々が新たな創造をトリガーするインスタンスを作成し、条件によって守られているため、コンストラクタは、同じコンストラクタを使用して新しいインスタンスを作成した場合でも、同様に完全に有効です。

public class Fail{ 
    public Fail(){ 
    new Fail(); 
    } 
} 

ここで唯一問題のある例です。コンパイラは文句を言わない。 をバイトコードに変換し、を実行することができます。その引数なしのコンストラクタがが

  • コンストラクタは新しい失敗
  • 新しい失敗を作成しようとすると呼ばれる
  • 割り当てられ

    • 新しい失敗:実行時には、しかし、あなたは、スタックオーバーフローを引き起こします...

    Cその引数なしのコンストラクタが

  • と呼ばれる
  • 割り当てられ、一般に、コンパイラはすべての無限再帰を防ぐことができないので、omfilerはこれを許可します。コンパイラは、バイトコードに変換できるものすべてを許可します。それは無条件に自分自身を呼び出す法やチェーンを検出した場合

    コンパイラは、しかし、警告を発行することができます。

  • 関連する問題