2015-03-01 25 views
5

Dopo aver appreso della classe interiore, capisco che ha un riferimento implicito alla classe esterna.La classe interna ha un riferimento implicito alla classe esterna e può perdere memoria

Ma il mio insegnante mi ha detto che il modo migliore non è usare la classe interna, preferisco usare la classe interna statica. Perché la classe interna potrebbe perdere memoria.

Qualcuno può gentilmente spiegare questo?

+3

http://stackoverflow.com/questions/10864853/when-exact-is-it-leak-safe-to-use-anonymous-inner-classes – jas

+0

@jas grazie, ma sono ancora molto confuso su di esso. Non posso commentare sotto questa soluzione a causa del basso punteggio. Nella soluzione, ha detto, "L'unico modo in cui ciò può accadere è se un oggetto esterno alla classe contenente mantiene un riferimento all'oggetto interno, indipendentemente dall'oggetto contenitore." Come può essere successo, se vogliamo avere accesso alla classe interna, dovremmo usare Outer.Inner giusto? non ha senso che un oggetto al di fuori della classe contenente mantenga un riferimento all'oggetto interno, indipendentemente dall'oggetto contenitore – Jie

risposta

5

Nella risposta al tuo commento (sarebbe illeggibile se l'ho postato nei commenti), a cui appartiene. Esempio di accesso alla classe interiore all'esterno dell'esterno.

public class Dog { 
    String name; 
} 

public class HugeKennel { 
    Double[] memmoryWaste = new Double[10000000]; 


    public List<Dog> getDogs() { 
     SneakyDog trouble = new SneakyDog("trouble"); 
     return Arrays.asList(trouble); 
    } 

    class SneakyDog extends Dog { 
     SneakyDog(String name) { 
      this.name = name; 
     } 
    } 

} 

da qualche altra parte nel codice

List<Dog> getCityDogs() { 
    List<Dog> dogs = new ArrayList<>(); 
    HugeKennel k1 = ... 
    dogs.addAll(k1.getDogs()); 
    HugeKennel k2 = ... 
    dogs.addAll(k2.getDogs()); 
    return dogs; 
} 

.... 

List<Dog> cityDogs = getCityDogs(); 
for (Dog dog: dogs) { 
    walkTheDog(dog); 
} 
// even though the Kenels were local variables in of getCityDogs(), they cannot be removed from the memory, as the SneakyDogs in the list are still referencing their parent kennels. 
//from now on, until all the dogs are not disposed off, the kennels also have to stay in the memory. 

Quindi non è necessario per accedere alla classe interna attraverso la sua classe parrent, una volta creato l'oggetto interno può essere usato come qualsiasi altro oggetto e può essere "fuoriuscito" dalla sua classe di contenitore, come nell'esempio precedente, quando la lista dei cani manterrà i riferimenti ai cani, ma ogni cane continuerà a "conoscere" il suo canile.

L'esempio collegato da StackTrace era correlato al caso d'uso tipico, quando le classi interne sono create "ad hock" come classi interne anonime, ma è lo stesso problema. Se si passa il riferimento a qualsiasi istanza di una classe interna, si passa anche al riferimento "passante" alla classe esterna.

Problemi correlati