1

Ich habe eine Klasse, die eine innere Klasse und eine Sammlung der inneren Instanzen hat:Inner Klassenreferenzinstanz umschließenden Klasse ist null

public class Outer { 

    private List<Inner> items = new ArrayList<Inner>(); 

    ... 

    public List<Inner> getItems(){ 
     return this.items; 
    } 

    public int getOuterX() { 
     ... 
    } 
    ... 

    public class Inner { 
     ... 
     public int getInnerX(){  
      return Outer.this.getOuterX(); // this line throws the exception 
     } 
    } 
} 

In anderer Klasse I über die Elemente einer Instanz Outer iterieren und rufen getInnerX() zu jeder:

for (Outer.Inner item : outer.getItems()) { 
    item.getInnerX(); 
} 

A NullPointerException innen getInnerX() geworfen wird, weil Outer.thisnull ist.

Ich weiß nicht, wie das passieren kann.

EDIT:

ich vorbereite das Beispiel wie @Sotirios Delimanolis gefragt und ich konnte den Fehler nicht reproduzieren. Also ist es etwas, das ich nicht in die Frage aufgenommen habe.

Ich verwende retrofit2 und Outer Objekt wird basierend auf einer json Antwort vom Server erstellt.

Das Element Attribut Outer hat Anmerkungen für den GSon Konverter:

@SerializedName("items") 
@Expose 
private List<Inner> items = new ArrayList<Inner>(); 

Outer hat keinen Konstruktor definiert auch nicht Inner. Hier

ist der Stack-Trace:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String 
com.example.server_comunication.datatypes.OrderResponse$Order.getStatus()' on a null object reference 
     at com.example.server_comunication.datatypes.OrderResponse$Order$Supply.forPlacement(OrderResponse.java:408) 
     at com.example.server_comunication.datatypes.OrderResponse$Order$Supply.getRemaining(OrderResponse.java:423) 
     at com.example.uiHelpers.UIFactoryPanels.drawPanelSuppliesEditor(UIFactoryPanels.java:142) 
     at com.example.OrderFragment.onCreateView(OrderFragment.java:85) 
     at android.app.Fragment.performCreateView(Fragment.java:2053) 
     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:894) 
     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067) 
     at android.app.BackStackRecord.run(BackStackRecord.java:833) 
     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1452) 
     at android.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:483) 
     at android.support.v13.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:145) 
     at android.support.v4.view.ViewPager.populate(ViewPager.java:1177) 
     at android.support.v4.view.ViewPager.populate(ViewPager.java:1025) 
     at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1545) 
     at android.view.View.measure(View.java:17430) 
     at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727) 
     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463) 
     at android.view.View.measure(View.java:17430) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 
     at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:668) 
     at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:735) 
     at android.view.View.measure(View.java:17430) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:430) 
     at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135) 
     at android.view.View.measure(View.java:17430) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) 
     at android.view.View.measure(View.java:17430) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:430) 
     at android.view.View.measure(View.java:17430) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 
     at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436) 
     at android.widget.LinearLayout.measureVertical(LinearLayout.java:722) 
     at android.widget.LinearLayout.onMeasure(LinearLayout.java:613) 
     at android.view.View.measure(View.java:17430) 
     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5463) 
     at android.widget.FrameLayout.onMeasure(FrameLayout.java:430) 
     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2560) 
     at android.view.View.measure(View.java:17430) 
     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2001) 
     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1166) 
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1372) 
     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1054) 
     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5779) 
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) 
     at android.view.Choreographer.doCallbacks(Choreographer.java:580) 
     at android.view.Choreographer.doFrame(Choreographer.java:550) 
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) 
+2

@ Daniel denke ich [tag: android] relevant ist. Dies sollte in Java ohne Java-Code-Manipulation nicht möglich sein. Etwas in Android könnte dies verursachen. Pablo, kannst du ein [MCVE] zur Verfügung stellen? –

+0

@SotiriosDelimanolis Guter Punkt, gerollt es zurück. –

+0

@SotiriosDelimanolis, ich arbeite am Beispiel. Genau wie ich es gepostet habe, konnte ich den Fehler nicht reproduzieren (ich vereinfachte es zu sehr), also füge ich neue Informationen hinzu. Vielen Dank. – Pablo

Antwort

4

Retrofit verwendet Gson und Gson Cheats. (Zum jetzigen Zeitpunkt) Es verwendet die Klasse sun.misc.Unsafe, um Ihre Klasse mit allocateInstance zu instanziieren. Dies überspringt alle Konstruktoren zusammen.

Im Falle einer inneren Klasse, any declared constructor will implicitly declare its first parameter as the enclosing type to represent the enclosing class' instance. Es gibt keine Möglichkeit für Gson, eine Instanz dieser einschließenden Klasse zu erstellen, aber selbst wenn dies der Fall ist, ist das egal. Gson überspringt den Konstruktor insgesamt und lässt diese implizite Outer.this Referenz als null zurück.

Die einfachste Lösung ist, Ihr Design zu ändern, die innere Klasse (n) loszuwerden. Alternativ können Sie einen benutzerdefinierten Deserializer registrieren und verwenden. In den Posts finden Sie Beispiele.

Related posts:

+0

Vielen Dank. Ich verwende innere Klassen, um die vom Server kommenden JSON-Strukturdaten abzugleichen. Ich werde mein Design ändern, wie du gesagt hast. – Pablo

Verwandte Themen