Vous avez le droit d'être confus, car la façon dont ces règles ont été écrites, sont déroutant.
Pour un ObjectRef, il est impossible d'avoir un type d'interface, comme chaque objet instancié a un type réel, non abstraite, peut-être la mise en œuvre d'une interface. Cela s'applique même aux instances générées pour les expressions lambda, qui ont un type (anonyme) non spécifié implémentant l'interface fonctionnelle.
Ainsi, au premier coup d'œil, il semble que cette partie de ces règles n'a pas de sens.Mais considérez le texte intégral:
Les règles suivantes sont utilisées pour déterminer si un ObjectRef qui ne null
est une instance du type résolu: Si S
est la classe de l'objet visé par ObjectRef et T
est la classe résolu, tableau ou type d'interface, instanceof détermine si ObjectRef est une instance de T
comme suit:
- Si
S
est une classe ordinaire (nonarray), puis:
- Si
T
est un type de classe, alors S
doit être la même classe que T
ou S
doit être une sous-classe de T;
- Si
T
est un type d'interface, alors S
doit implémenter l'interface T
.
- Si
S
est un type d'interface, puis:
- Si
T
est un type de classe, alors T
doit être l'objet.
- Si
T
est un type d'interface, alors T
doit être la même interface que S
ou une superinterface de S
.
- Si
S
est une classe représentant le type de tableau SC[]
, c'est un ensemble de composants de type SC
, puis:
- Si
T
est un type de classe, alors T
doit être l'objet. Si T
est un type d'interface, alors T
doit être l'une des interfaces implémentées par les tableaux (JLS §4.10.3).
- Si
T
est un type tableau TC[]
, qui est un ensemble de composants de type TC
, puis une des options suivantes doivent être remplies:
TC
et SC
sont le même type primitif.
TC
et SC
sont des types de référence et le type SC
peut être converti en TC
par ces règles d'exécution.
Comme il est impossible pour l'objet réel référencé par ObjectRef avoir un type d'interface, seuls les deux autres balles sont applicables; son type est soit une "classe ordinaire (non-array)", soit un type tableau. Dans ce dernier cas, la dernière phrase est la plus intéressante, car elle renvoie aux règles citées dans leur ensemble, à appliquer aux types de composants T
et S
si les deux sont des tableaux d'un type de référence.Et le type de composant peut être un type d'interface.
Vous pouvez tester ces règles en utilisant une instance de tableau réel d'un type d'interface, la vérification par rapport aux autres types de tableau:
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
Il pense, il serait moins confus, si le cas d'interface a été décrite dans le tableau spécial, où il peut s'appliquer. D'un autre côté, ces trois cas suivent les règles générales d'attribution formelles, de sorte qu'ils sont plus faciles à reconnaître sous cette forme.
'S est la classe de l'objet référencé par * objectref *': dans ce cas, 'StringBuilder'. La troisième ligne d'impression 'false' est correcte. – EJP
@EJP Mais ne pensez-vous pas que la première règle que j'ai mentionnée est différente de ce qui devrait être imprimé à partir du code que j'ai donné? String est Object, n'est-ce pas – Rui