Pourquoi ce code instanceof fonctionne et ne provoque pas une erreur de compilation?

StackOverflow https://stackoverflow.com/questions/3897467

  •  29-09-2019
  •  | 
  •  

Question

Dans le code suivant, le type de x est I (bien que x J met également en œuvre mais c'est pas connu au moment de la compilation), alors pourquoi est-ce que le code à (1) ne se traduit pas par une erreur de compilation. Parce que lors de la compilation du type de référence est considéré.

public class MyClass {
    public static void main(String[] args) {
        I x = new D();
        if (x instanceof J) //(1)
            System.out.println("J");
    }
}

interface I {}

interface J {}

class C implements I {}

class D extends C implements J {}
Était-ce utile?

La solution

instanceof est utilisé utilisé pour la détermination de l'exécution du type d'objet. Vous essayez de déterminer si x est vraiment un objet de type J lorsque le programme est en cours d'exécution, il compile.

Pensiez-vous qu'il devrait se traduire par une erreur de compilation parce que vous pensez que le compilateur ne connaît pas le type de x?

Modifier

Kirk Woll a commenté (merci Kirk Woll!), Si vous vérifiez si x est instanceof une classe de béton, et le compilateur peut déterminer le type de x, vous obtiendrez une erreur au moment de la compilation.

De la spécification du langage Java:

  

Si une distribution du RelationalExpression au referenceType serait rejetée comme une erreur de compilation, l'expression instanceof relationnelle produit également une erreur de compilation. Dans une telle situation, le résultat de l'expression instanceof ne pourrait jamais être vrai.

A titre d'exemple:

import java.io.Serializable;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;

class SerializableClass implements Serializable
{
   private writeObject(ObjectOutputStream out) {}
   private readObject(ObjectInputStream in) {}
}

public class DerivedSerializableClass extends SerializableClass
{
   public static void main(String[] args)
   {
      DerivedSerializableClass dsc = new DerivedSerializableClass();

      if (dsc instanceof DerivedSerializableClass) {} // fine
      if (dsc instanceof Serializable) {} // fine because check is done at runtime
      if (dsc instanceof String) {} // error because compiler knows dsc has no derivation from String in the hierarchy

      Object o = (Object)dsc;
      if (o instanceof DerivedSerializableClass) {} // fine because you made it Object, so runtime determination is necessary
   }
}

Autres conseils

est un opérateur instanceof d'exécution, pas de compilation, de sorte qu'il est en cours d'évaluation en utilisant le type réel de l'objet référencé.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top