2010-11-10 8 views
23

Das ganze Generics-Ding wirft mich irgendwie für eine Schleife, und mehr so ​​die RTT.Java isInstance vs. instanceOf-Operator

Spezifika? Ah gut hier ist der Kern:

enum QueryHelper { 
    query1, 
    query2; 
    static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) { 
    if (expectedReturn.isInstance (SomeRelatedClass.class)) 
     return query1; 
    else 
     return query2; 
    } 
} 

und dann würde ich es wie so nennen:

... 
QueryHelper helper = QueryHelper.getQueryHelper(SomeRelatedClass.class); 
... 

Dieses so ist, dass ich wirklich flexibel die Abfrage Rückgabetyp in der eigentlichen Helfer zuweisen. Es wird gegossen und Objekte erstellt. Was ich sehe ist, dass es keine Übereinstimmung gibt, sollte ich das auf eine andere Weise tun? Oder ist die ganze Idee einfach schlecht?

Und das eigentliche Herz ist, dass ich den Unterschied zwischen class.isInstance und dem Operator instanceOf nicht verstehe? Soll ich das letztere benutzen?

Antwort

29

Diese ist so, dass ich den Anfrage-Rückgabetyp im eigentlichen Helfer wirklich flexibel zuweisen kann.

Es gibt nichts, flexibel über den Rückgabetyp dieser Methode

static <T> QueryHelper getQueryHelper (Class<T> expectedReturn) { 
    if (expectedReturn.isInstance (SomeRelatedClass.class)) 
     return query1; 
    else 
     return query2; 
} 

Es wird immer eine Instanz von QueryHelper zurückzukehren. Wenn Sie den Rückgabetyp flexibel sein wollen, müssen Sie es als etwas zu definieren, wie:

static <T> T getQueryHelper (Class<T> expectedReturn) { 
} 

nun der Rückgabetyp ist flexibel, da sie von der Art des Arguments abhängen

Und Das wirkliche Herz ist, dass ich den Unterschied zwischen class.isInstance und dem instanceOf-Operator nicht verstehe?

Der Unterschied besteht darin, dass Instanceof funktioniert ein Typ-prüfen, ob zum Zeitpunkt der Kompilierung festgelegt ist, zum Beispiel:

static boolean isInstance(Object myVar) { 
    return (myVar instanceof Foo); 
} 

wird immer diese meineVar überprüfen ist eine Instanz von Foo, während

static <T> boolean isInstance(Object myVar, Class<T> expectedType) { 
    return expectedType.isInstance(myVar); 
} 

überprüft, dass myVar eine Instanz von expectedType ist, aber expectedType kann jedes Mal ein anderer Typ sein, wenn die Methode aufgerufen wird

+0

Ihre Verwendung ex reichlich für isInstance ist rückwärts. Wäre zu erwarten Type.isInstance (myVar); – Affe

+0

Vielen Dank für die Klärung, dass - ich def brauchte, um zu verlangsamen und zu denken, als ich diesen Code schrieb. Es hat sich seitdem in Form verändert, um tatsächlich nützlich zu sein. Danke noch einmal! – rybit

1

Das erwartete Argument von isInstance ist ein Objekt, das eine Instanz der Klasse sein kann, die von Ihrem Klassenobjekt repräsentiert wird. Was Sie damit vergleichen, ist eine Instanz der Klasse ... java.lang.Class! Also wird es nicht zusammenpassen.

zB wäre wahr:

Class.class.isInstance(SomeRelatedClass.class); 

auch wahr wäre (ohne architektonische Kommentar auf die geistige Gesundheit der tatsächlich den Aufbau Ihrer Abfrage Helfer auf diese Weise)

expectedReturn.isInstance(new SomeRelatedClass()); 
3

Class.isInstance() doesn arbeite nicht wie es dein Code erwartet. Es testet, ob das Objekt, das Sie übergeben, eine Instanz der Klasse ist. In Ihnen Code:

expectedReturn.isInstance(SomeRelatedClass.class) 

Das Objekt, das Sie übergeben, ist ein Klassenobjekt. Versuchen Sie stattdessen diese, die true zurückgibt:

Class.class.isInstance(SomeRelatedClass.class); 

Was Sie wahrscheinlich suchen, ist Class.isAssignableFrom(), zB:

Object.class.isAssignableFrom(Class.class); 

Bedeutet, dass Sie dies tun können:

Class klass = ...; 
Object o = klass;