2016-01-08 10 views
5

ho questa classe interna non statica che provoca perdite di memoria, perché contiene un implicito riferimento alla classe contenitrice:Soluzione per accedere metodo membro static da una classe interna statica

private class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub { 

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

Per fermare la fuoriuscita, ho bisogno di fare è statica:

private static class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub { 

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

e 'impossibile fare updateCalendar() statica perché in esso accede altre variabili non statici e diventa un pasticcio. Cosa faccio?

+0

possiedi il superclasse? – Terje

+2

Non capisco perché debba essere statico. Se si desidera chiamare un metodo della classe di inclusione, è comunque necessario tale riferimento. Non vedo davvero la perdita di memoria lì. –

+0

Cosa intendi con _che causa perdite di memoria_? Quando l'istanza della classe interna è GC, l'istanza esterna sarà troppo (se non c'è altro riferimento). E quando l'istanza interiore rimane nell'heap, deve rimanere anche quella esterna (perché comunque stai chiamando il metodo esterno). – Codebender

risposta

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

È necessario passare un riferimento a un'istanza della classe esterna. E devi rendere pubblica la tua classe statica.

public static class CalendarScheduleUpdatedEventListener extends ScheduleUpdatedEventListener.Stub { 

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

Ci proverò, ma perché non colpirà questa volta? Il riferimento sarà GC? –

+0

@ J.K. Finché non ti aggrappi al riferimento non può perdere. – Ralf

+1

In generale, penso che questa sia una soluzione ragionevole. Tuttavia, non sono sicuro che risolverà questo problema specifico. Il riferimento alla classe esterna viene trapelato quando l'unico riferimento rimanente ad esso è il riferimento implicito creato dalla classe interna. Per passare un'istanza di 'TheOuterClass' al metodo' onScheduleUpdatedEvent() ', qualcun altro deve avere anche un riferimento ad esso; quindi, non è trapelato. –

Problemi correlati