2016-01-08 16 views
5

mam ten zakaz statyczną klasę wewnętrzną, która powoduje wycieki pamięci, ponieważ posiada pośrednie odniesienie do klasy okalającego:Obejście dostęp non-statycznej metody członek od statycznej klasy wewnętrznej

private class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub { 

    @Override 
    public void onScheduleUpdatedEvent() throws RemoteException { 
     updateCalendar(); 
    } 
} 

w celu zatrzymać go przed przeciekaniem, muszę zrobić to statyczna:

private static class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub { 

    @Override 
    public void onScheduleUpdatedEvent() throws RemoteException { 
     updateCalendar();-> Compiler error - trying to access a non-static... 
    } 
} 

jest niemożliwe, aby updateCalendar() statyczny, ponieważ mnie to dostęp do innych zmiennych non-statyczne i staje się bałagan. Co ja robię?

+0

Czy jesteś właścicielem superklasę? – Terje

+2

Nie do końca rozumiem, dlaczego to musi być statyczne. Jeśli chcesz wywołać metodę klasy otaczającej, mimo to potrzebujesz tego odwołania. Naprawdę nie widzę przecieku pamięci. –

+0

Co rozumiesz przez to, co powoduje wycieki pamięci? Gdy wewnętrzna instancja klasy jest GCed, zewnętrzna instancja też będzie (Jeśli nie ma innych odniesień). A gdy wewnętrzna instancja pozostaje w stosie, zewnętrzna też musi pozostać (bo i tak nazywacie zewnętrzną metodą). – Codebender

Odpowiedz

4
private static class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub { 
    final WeakReference<Object> obj; //change <Object> to whatever type it is. 

    CalendarScheduleUpdatedEventListener(Object x) { 
     this.obj = new WeakReference<>(x); 
    } 

    @Override 
    public void onScheduleUpdatedEvent() throws RemoteException { 
     Object o = obj.get(); 
     if (o == null) { 
      //because a WeakReference will be null if it has been garbage collected. 
      return; //or throw some exception 
     } 
     o.updateCalendar(); 
    } 
} 
6

Musisz podać odniesienie do instancji swojej zewnętrznej klasy. I musisz upublicznić swoją statyczną klasę.

public static class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub { 

    @Override 
    public void onScheduleUpdatedEvent(final TheOuterClass instance) throws RemoteException { 
     instance.updateCalendar(); 
    } 
} 
+0

Spróbuję tego, ale dlaczego nie wyciek tym razem? Czy odniesienie zostanie oznaczone GC? –

+0

@ J.K. Dopóki nie będziesz się trzymał referencji, nie może przeciekać. – Ralf

+1

Ogólnie uważam, że jest to rozsądne rozwiązanie. Jednak nie jestem pewien, czy rozwiąże to konkretny problem. Odwołanie do klasy zewnętrznej jest nieszczelne, gdy jedynym pozostałym odniesieniem do niego jest niejawne odwołanie tworzone przez klasę wewnętrzną. Aby przekazać instancję 'TheOuterClass' do metody' onScheduleUpdatedEvent() ', ktoś inny również musi mieć do niej odniesienie; dlatego nie jest przeciekany. –

Powiązane problemy