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

Non è strano creare un oggetto nella definizione della stessa classe? Perché poi in risposta - questo oggetto crea un nuovo oggetto, quindi questo nuovo oggetto ne crea un altro, e il ciclo infinito inizia a non finire mai finché la memoria non è piena.Quando è corretto creare oggetti di una classe all'interno di un metodo di quella classe?

risposta

13

Non è strano per creare un oggetto nella definizione della stessa classe che in risposta all'oggetto creare un nuovo oggetto di questo nuovo oggetto creare un altro e il ciclo infinito inizia

No, il metodo principale viene eseguito una sola volta quando si esegue il programma. Non verrà eseguito di nuovo. Quindi, l'oggetto verrà creato solo una volta.

Pensa al tuo metodo principale per stare fuori dalla classe. Che crea un'istanza della classe e utilizza l'istanza creata. Pertanto, quando si crea un'istanza dal metodo principale, il costruttore viene richiamato per inizializzare lo stato dell'istanza, quindi, quando viene restituito il costruttore, viene eseguita l'istruzione successiva del metodo principale.

In realtà, è possibile considerare il metodo principale di non far parte dello stato dell'istanza della classe.

Tuttavia, hai creato l'istanza della classe all'interno del costruttore (ad esempio 0-arg) e il riferimento come variabile di riferimento dell'istanza, che quindi si trasformerà in una ricorsione infinita.

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

significa che tutti i metodi sono fuori dalla definizione della classe solo la variabile di classe viene creata quando viene creato un oggetto? –

+0

@RaviKumarMistry. Non l'ho detto Solo il metodo principale può essere considerato virtualmente fuori classe. Una classe contiene anche altri metodi oltre a quello principale. Sono solo nella tua classe e una parte del tuo stato di istanza. –

+0

@RaviKumarMistry. L'unica ragione per cui dobbiamo inserire main all'interno di una classe, è che non possiamo avere metodi al di fuori di alcuna classe in Java. –

1

Non è molto strano. Tutte le lingue orientate agli oggetti di cui sono a conoscenza lo consentono. Il codice è parte semanticamente della definizione dell'oggetto, ma in pratica può essere considerato separato dallo stato effettivo di ogni oggetto dato. Quindi non esiste un ciclo perché la costruzione dell'oggetto non chiama il metodo (a meno che, naturalmente, non lo faccia - allora hai un problema).

0

Quando si utilizza new per creare costruttori di oggetti, viene chiamato il quale inizializza la variabile di istanza in questo modo finché tutti i costruttori della super classe sono stati chiamati. se si mette il codice all'interno del costruttore che verrà eseguito ogni volta che si crea un oggetto

4

si avrebbe solo un ciclo infinito (errore di overflow dello stack) se si è tentato di fare il seguito:

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

E altrove, si tenta di creare un oggetto della classe TestClass.

0

All'avvio di un programma, esegue il metodo principale. In java non puoi creare un metodo al di fuori di una classe. Tutti i metodi devono essere incapsulati all'interno di una classe. Pertanto, il metodo principale come punto di accesso al programma deve essere all'interno di una classe. Quando si esegue questo programma, il metodo principale verrà eseguito una volta e verrà eseguito il codice al suo interno. Nel tuo caso crea un oggetto della classe di inclusione TestClass. Questo non deve accadere. Può creare oggetti anche al di fuori di questa classe. Riceverai solo un ciclo infinito come spiegato nella risposta di @ adarshr.

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

Questo è un codice perfettamente valido. Quando viene chiamato il metodo main, non esiste alcuna istanza precedente di TestClass (non è necessario, perché il metodo main è static).

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

Ciò è perfettamente valido pure. Quando crei una nuova istanza di Test2, contiene il metodo clone, ma il metodo non viene eseguito automaticamente. Solo quando viene chiamato il metodo clone, viene creata un'altra istanza di Test2.

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

è perfettamente valido e, anche se il costruttore crea una nuova istanza utilizzando lo stesso costruttore, perché la creazione è sorvegliata da un condizionale, in modo da creare un'istanza volte innesca una nuova creazione.

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

È l'unico esempio problematico qui. Il compilatore non si lamenta. È possibile convertire in byte code e può essere eseguito. Alla fase di esecuzione, tuttavia, si causa un overflow dello stack:

  • un nuovo Fail allocato
  • suo costruttore no-arg è chiamato
  • il costruttore cerca di creare un nuovo Fail
  • un nuovo Fail allocata
  • suo costruttore no-arg è chiamato
  • ...

Il c ompiler permette questo, perché, in generale, il compilatore non può impedire la ricorsione infinita. Il compilatore consente tutto ciò che può essere tradotto in bytecode.

Il compilatore, però, può emettere un avvertimento se rileva un metodo o una catena metodo di chiamate si incondizionatamente.

Problemi correlati