2008-12-16 6 views
9

In einem Haufen o‘Orte in meinem Code, habe ich so etwas wie diese:Ist es eine gute Übung, die Klasse durch Klasse <zu ersetzen? Erweitert Objekt> um Warnungen zu vermeiden?

public Class mySpecialMethod() { 
    return MySpecialClass.class; 
} 

, die die Warnung

Klasse verursacht, ist eine rohe Art. Verweise auf generischer Typ Klasse sollte parametrisiert sein.

Aber wenn ich

Class

mit

Class<? extends Object>

die Warnung geht weg ersetzen.

Ist diese einfache Übung in Ordnung, oder könnte sie später Probleme verursachen?

Antwort

15

Es ist die richtige Sache nur zu tun, wenn es wirklich keine gemeinsame Basisklasse oder Schnittstelle gibt, die das Klassenobjekt repräsentieren muss.

Auch Class<?> ist effektiv das gleiche wie Class<? extends Object>.

6

Je nachdem, was Sie erreichen wollen, können Sie noch präziser sein:

public Class<MySpecialClass> mySpecialMethod() { 
    return MySpecialClass.class; 
} 
4

Nicht wirklich ein Java-Programmierer hier, aber einige gute Papiere über Generika lesen.

Ja, Sie sollten einige Wildcard oder den genauen Typ (Class<MySpecialClass>) hinzufügen, um Sicherheit hinzuzufügen. Der Grund ist, dass Klasse ein Generikum ist. So sind Class<Bar> und Class<Foo> die gleichen nach dem Löschen ihres generischen Typparameters. Sie alle werden Class, der sogenannte Rohtyp. Diese Löschung geschieht beim Kompilieren. Einige Beispiele, dies zu veranschaulichen, wo der Compiler Sie mit automatischen Gießen hilft (die Ausnahmebehandlung der Kürze halber weggelassen):

class Mine { } 

class Vara { 
    public static void main(String... args) { 
     { // works. translated to Mine m = (Mine) c.newInstance(); 
      Class<Mine> c = Mine.class; 
      Mine m = c.newInstance(); 
     } 
     { // doesn't work. need a cast: Mine m = (Mine) c.newInstance(); 
      Class c = Mine.class; // also Class<?> or Class<? extends Object> 
      Object o = c.newInstance(); // but this works. pointing to a Mine 
      Mine m = (Mine) c.newInstance(); // needs a manual cast 
     } 
    } 
} 

sagen Class<?> (und das Äquivalent Class<? extends Object>), sagen Sie den Compiler Sie wirklich eine Klasse, deren T wollte, ist Object und hat nicht versehentlich den Rohtyp verwendet. Aber es wird keine Bequemlichkeitscasts hinzufügen. All diese Generics machen automatische Cast für Sie, um von Object auf den Zieltyp zu übertragen. Generics sind die gleichen, ob mit Typ U oder mit Typ T zur Laufzeit aus Kompatibilitätsgründen mit älteren Java-Versionen verwendet.