Sie haben das Recht, verwirrt zu sein, da die Art, wie diese Regeln geschrieben wurden, sind verwirrend.
Für ein objectref, ist es unmöglich einen Schnittstellentyp zu haben, da jedes Objekt instanziiert eine tatsächliche, nicht abstrakte Art hat, vielleicht eine Schnittstelle zu implementieren. Dies gilt sogar für die Instanzen, die für Lambda-Ausdrücke generiert wurden, die einen nicht spezifizierten (anonymen) Typ haben, der die funktionale Schnittstelle implementiert.
So scheint es auf den ersten Blick, dass dieser Teil dieser Regeln keinen Sinn macht.Aber betrachten Sie den kompletten Text:
Die folgenden Regeln verwendet werden, um zu bestimmen, ob ein objectref, die nicht null
ist eine Instanz der aufgelösten Art: Wenn S
ist die Klasse des genannte Objekts durch objectref und T
wird die aufgelöste Klasse, ein Array oder Schnittstellentyp, instanceof bestimmt, ob objectref ist eine Instanz T
wie folgt:
- Wenn
S
eine gewöhnliche (Nonarray) Klasse ist, dann gilt:
- Wenn
T
ein Klassentyp ist, dann S
muss die gleiche Klasse wie T
sein, oder S
muss eine Unterklasse von T sein;
- Wenn
T
ein Schnittstellentyp ist, muss S
die Schnittstelle T
implementieren.
- Wenn
S
ist ein Interface-Typ, dann:
- Wenn
T
ist ein Klasse-Typ, dann T
Objekt sein muss.
- Wenn
T
ein Schnittstellentyp ist, muss T
die gleiche Schnittstelle wie S
oder ein Superinterface von S
sein.
- Wenn
S
ist eine Klasse, die den Array-Typs SC[]
, das heißt, eine Anordnung von Komponenten des Typs SC
, dann gilt:
T
Wenn ein Klassentyp ist, dann T
Objekt sein muss.
- Wenn
T
ein Schnittstellentyp ist, muss T
eine der von Arrays implementierten Schnittstellen sein (JLS §4.10.3).
T
Wenn ein Array-Typ TC[]
, das heißt, eine Anordnung von Komponenten des Typs TC
, dann einer der folgenden Schritte müssen wahr sein:
TC
und SC
ist der gleiche Urtyp.
TC
und SC
sind Referenztypen und der Typ SC
kann mithilfe dieser Laufzeitregeln in TC
umgewandelt werden.
Da es für das eigentliche Objekt durch verwiesen unmöglich ist objectref einen Schnittstellentyp haben, nur die beiden anderen Kugeln gelten; Sein Typ ist entweder eine "normale (Nicht-Array-) Klasse" oder ein Array-Typ. Im letzteren Fall ist der letzte Satz der interessante, da er sich auf die zitierten Regeln als Ganzes bezieht und auf die Komponententypen T
und S
angewendet wird, wenn beide Arrays eines Referenztyps sind.Und der Komponententyp kann ein Schnittstellentyp sein.
So können Sie diese Regeln testen eine tatsächliche Array-Instanz von einem Schnittstellentyp verwendet wird, die Überprüfung gegen andere Array-Typen:
Object o = new Collection[0]; // SC is Collection
System.out.println(o instanceof Object[]); // TC is class type Object -> true
System.out.println(o instanceof String[]); // TC is class type other than Object -> false
System.out.println(o instanceof Collection[]); // TC == SC -> true
System.out.println(o instanceof Iterable[]); // TC is super interface of SC -> true
System.out.println(o instanceof List[]); // TC is not super interface SC -> false
Es denken, wäre es weniger verwirrend sein, wenn die Schnittstelle Fall innerhalb der beschrieben wurde Array Sonderfall, wo es gelten kann. Auf der anderen Seite folgen diese drei Fälle den allgemeinen formalen Zuordnungsregeln, so dass sie in dieser Form leichter zu erkennen sind.
'S ist die Klasse des Objekts, auf das mit * objectref *' verwiesen wird: in diesem Fall 'StringBuilder'. Die dritte Zeile, die 'false' druckt, ist korrekt. – EJP
@EJP Aber denkst du nicht, dass die erste Regel, die ich erwähnt habe, anders ist als die, die aus dem Code gedruckt werden sollte? String ist Objekt, ist es nicht – Rui