Question

import java.util.Collection;


public class Test
{
    public static void main(String[] args)
    {
        Collection c = null;
        Test s = null;

        s = (Test) c;
    }
}

Dans l'exemple de code ci-dessus, je transforme un objet de collection en objet Test. (en ignorant le pointeur nul). Le test a pas de relation avec Collection, mais ce programme passera tous les contrôles au moment de la compilation.

Je me demande pourquoi c'est. Mon hypothèse est que les interfaces sont ignorées car elles sont trop compliquées. Ils n’ont pas de super-type commun et chaque classe peut implémenter plusieurs interfaces. La hiérarchie classe / interface serait donc trop compliquée pour effectuer une recherche efficace?

Autre que la raison pour laquelle je suis perplexe cependant. Est-ce que quelqu'un sait?!

Était-ce utile?

La solution

" Non final " est un mot clé ici. Vous pouvez avoir une autre classe

public class Test2 extends Test implements Collection

dont l'instance finira par être assignée à s , ce qui rend un casting parfaitement légal.

Autres conseils

Parce qu'une sous-classe de Test peut potentiellement être aussi un sous-type de Collection ! La spécification de langage est conçue pour être un peu flexible afin de permettre des conversions pouvant être vérifiées au moment de l’exécution.

Nous pouvons le voir sous un angle différent: toute classe non finale peut être convertie en N'IMPORTE QUELLE interface

.
import java.util.function.Predicate;

public class Test {
    public static void main(String[] args) {
        Predicate check;

        try {
            /*It's ok to cast to ANY interface because the Base class is not final.
              Java compiler allows it because some class may extend it 
              and implement the predicate interface. 
              So java compiler can check it only at runtime time not compile time.             
            */
            check = (Predicate)(new Base());

            /*
             Java compiler doesn’t allow it because the BaseFinal is final.
             And it means that no one can extend it and implement interface Predicate. 
             So java compiler can check it at compile time.
            */
            //check = (Predicate)(new BaseFinal()); 
        } catch (ClassCastException e) {
            System.out.println("Class Cast Exception");
        }
        check = (Predicate)(Base)(new Child());
    }    
}
final class BaseFinal {};

class Base {}

class Child extends Base implements Predicate {
    public boolean test(Object t) { return true; }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top