2015-03-01 12 views
5

Po zapoznaniu się z klasą wewnętrzną rozumiem, że ma ona ukryte odniesienie do klasy zewnętrznej.Klasa wewnętrzna ma niejawne odniesienie do klasy zewnętrznej i może przeciekać pamięć

Ale mój nauczyciel powiedział mi, że najlepszym sposobem nie jest używanie wewnętrznej klasy, wolą używać statycznej klasy wewnętrznej. Ponieważ wewnętrzna klasa może przeciekać pamięć.

Czy ktoś może to wyjaśnić?

+3

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

+0

@jas dzięki, ale nadal jestem bardzo niejasna. Nie mogę skomentować tego rozwiązania z powodu niskiego wyniku. W rozwiązaniu napisano: "Jedynym sposobem, w jaki może się to zdarzyć, jest sytuacja, gdy obiekt znajdujący się poza klasą zawiera odniesienie do obiektu wewnętrznego, bez względu na obiekt zawierający." Jak to się mogło stać, jeśli chcemy uzyskać dostęp do wewnętrznej klasy, powinniśmy użyć hasła Outer.Inner? nie ma sensu, aby obiekt znajdujący się poza klasą zawierał odniesienie do obiektu wewnętrznego, bez względu na obiekt zawierający – Jie

Odpowiedz

5

W odpowiedzi na Twój komentarz (byłby nieczytelny, jeśli umieściłem go w komentarzach), gdzie należy. Przykład dostępu do wewnętrznej klasy poza zewnętrzną.

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; 
     } 
    } 

} 

gdzieś indziej w kodzie

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. 

Więc nie trzeba, aby uzyskać dostęp poprzez wewnętrzną klasę swojej klasie Parrent, gdy tworzony jest wewnętrzny obiekt może być używany jak każdy inny przedmiot i może być "wyciekł" poza swoją klasę kontenerową, tak jak w powyższym przykładzie, gdy lista psów będzie zawierała odniesienia do psów, ale każdy pies będzie nadal "wiedział" o swojej hodowli.

Połączony przykład z StackTrace był związany z typowym przypadkiem użycia, kiedy klasy wewnętrzne są tworzone jako "hock" jako anonimowe klasy wewnętrzne, ale jest to ten sam problem. Jeśli przekażesz odniesienie do dowolnej instancji klasy wewnętrznej, będziesz także "przekazywał" odwołanie do klasy zewnętrznej.

Powiązane problemy