2016-09-23 2 views
3

Ich bin ein Java-Neuling und vor kurzem habe ich in einige Überlegungen über den folgenden Android Beispielcode:Analyse Casting

TextView txt = (TextView) findViewById(R.id.activity_display_message);

TextView ein Kind View Klasse. Und findViewById gibt ein View Objekt zurück.

Ich wollte verstehen, wie und warum müssen wir explizit die zurückgegebene View zu TextView, wenn das zurückgegebene Objekt tatsächlich ein TextView sein muss, sonst wird das Casting wirft eine Ausnahme werfen.

Also, das ist mein Versuch zu simulieren, was mit diesem Mockup Code hinter den Kulissen vor sich geht:

class View{} 
class TextView extends View{} 

public class A{ 

    // simple hard coded check of the ID 
    public static View findViewById(int id){ 

     if (id == 1){ 
      return new View(); 
     } 
     else{ 
      return new TextView(); 
      //return ((View)new TextView()); // This also works 
     } 

    } 


    public static void main(String[] args){ 

     TextView txt = (TextView)findViewById(2); // Works fine 
     //TextView txt2 = findViewById(2); INCOMPATIBLE TYPES ERROR because the returned type is View 
     View v = findViewById(2); // Works fine 

     View view = new View(); 
     //TextView test = (TextView) view; // cast error 

     View view2 = new TextView(); 
     TextView test2 = (TextView) view2; // Works OK 


    } 
} 

Fazit:

Es stellt sich heraus, dass findViewById tatsächlich View wirft zurückgeschickte Element. Ich nehme an, es liegt daran, dass der definierte Rückgabewert der Methode View ist und Java das Ergebnis automatisch auf View umsetzt.

Bitte sagen Sie mir, wenn ich es richtig mache.

+0

Kann dies http://stackoverflow.com/questions/22805869/cast-result-findviewbyid-android-method hilft! – Raghunandan

+0

ja du hast Recht, Java arbeitet auf diese Weise – RMachnik

Antwort

1

Wie Sie in der Frage beschreiben, findViewById(R.id.activity_display_message); gibt ein View Objekt, in diesem Fall Sie die Programmierer wissen, dass diese besonderen View ist eigentlich ein TextView Objekt, aber findViewById verspricht nur ein View oder eine Instanz jeder Klasse zurückzukehren das stammt von View ab, da jede Klasse, die von View abstammt, immer noch eine View ist, könnte es nur spezifischere Details verfügbar haben.

All das findViewById wird garantiert zurückgegeben wird, ist oder erweitert View. Wenn Sie das zurückgegebene Objekt so behandeln möchten, als wäre es eine bestimmte Unterklasse von View, müssen Sie das von findViewById zurückgegebene Objekt in diese Unterklasse umwandeln.

Von Ihrem Beispiel View view = new View(); // This is a View, it is NOT a TextView View textView = new TextView(); // TextView is a View, but it also has TextView stuff going on... //TextView test = (TextView) view; // cast error

1

Grund für die Ausnahme im Fall 1 ist Ihre View-Klasse bcz ist nicht bekannt, dass Unterklasse Textview genannt ... wo, wie im Fall 2 Textview bekannt ist, dass sie zur Familie gehören der Sichtklasse.

upcast - Casting eines Subtype-Objekts in einen Supertype und dies heißt Upcast. In Java müssen wir keine explizite Umwandlung hinzufügen, und Sie können das Objekt direkt zuweisen. Der Compiler versteht den Wert und übergibt ihn an den übergeordneten Typ. Indem wir dies tun, heben wir ein Objekt auf eine allgemeine Ebene. Wenn wir bevorzugen, können wir eine explizite Umwandlung und keine Probleme hinzufügen.

downcast - Die Umwandlung eines Supertyps in einen Subtyp wird als Downcast bezeichnet. Dies ist die am häufigsten durchgeführte Besetzung. Auf diese Weise teilen wir dem Compiler mit, dass der im Basisobjekt gespeicherte Wert vom Super-Typ ist. Dann bitten wir die Laufzeit, den Wert zuzuweisen. Aufgrund von Downcast erhalten wir Zugriff auf Methoden des Subtyps für dieses Objekt.

ClassCastExcpetion - Wir erhalten ClassCastException in einem Downcast. Im Prinzip garantieren wir dem Compiler, dass der Instanzwert von subtype ist und bitten ihn um die Umsetzung. Aber während der Laufzeit ist der Wert aufgrund unvorhergesehener Umstände nicht vom erwarteten Subtyp. In solchen Fällen erhalten wir ClassCastException.

0

Auch wenn die Methode eine View zurückgibt, da TextView eine Unterklasse von View ist, kann sie von der Methode sicher zurückgegeben werden.

Nehmen Sie zum Beispiel die folgende rechtliche Zuordnung:

View view = new TextView(); // Legal, no compiler errors. TextView is a subclass of View, so it can be safely 'downgraded' 

Und die folgende illegale Zuordnung:

TextView textView = new View(); // Illegal, compatibility error 

Es ist genau die gleiche Art und Weise mit der Rückkehr wird die TextView auf eine View herabgestuft. Wie für Ihre Frage, ob Sie herausfinden können, ob es eine TextView ist, die zurückgegeben wird, können Sie den Operator instanceof verwenden.