3 votes

Transformer une superclasse en sous-classe

Imaginez une classe Extension du chalet et le code

Building building = new Building();
Cottage cottage = (Cottage)building;

Il est tout à fait logique que Bâtiment ne peut pas être lancé vers Cottage Compte tenu de la nature de l'héritage Java, ce qui n'a pas de sens (pour moi), c'est que cela compile. Pourquoi compile-t-il et ensuite lance-t-il un runtime ClassCastException ?

N'est-il pas évident que bâtiment est une référence à un Bâtiment avant d'exécuter le programme ?

Comme il s'agit d'une question générale, je sais que je risque d'avoir un doublon :) mais je n'ai pas trouvé de réponse à la question "pourquoi ça compile" :)

EDIT2 J'ai accepté une excellente réponse ici (sans parler de la discussion qui suit :) ), mais je trouve toujours la réponse acceptée dans Le casting Java entraîne une erreur d'exécution au lieu d'une erreur de compilation le plus intéressant...

EDIT J'ai édité IllegalCastException et mettre le bon ClassCastException

10voto

Rohit Jain Points 90368

C'est parce que le compilateur ne sait pas quel est l'objet de votre référence Building se réfère.

Ainsi, dans le cas ci-dessous, où vous avez un classe de base référence, pointant vers sous-classe objet : -

Building building = new Cottage();
Cottage cottage = (Cottage)building;

Cela fonctionnerait parfaitement. Il s'agit donc d'une durée d'exécution pour savoir s'il s'agit d'un cast valide ou non. Par conséquent, le compilateur ne lancera pas d'erreur pour cela.

N'est-il pas évident que le bâtiment est une référence à un B avant d'exécuter le programme ?

No. Absolument pas. Le type d'objet référencé n'est pas connu avant l'exécution. Rappelez-vous toujours cela, Compilateur vérifie toujours le type de référence . Le type d'objet réel est vérifié au moment de l'exécution.

Ce concept est connu sous le nom de Polymorphisme où le même type de référence peut pointer vers des objets de différents sous-types. Vous pouvez consulter Google à ce sujet et vous obtiendrez de nombreuses ressources à lire.

3voto

Nathan Hughes Points 30377

Une partie de la fonction du casting est de faire taire le compilateur, vous dites que vous savez mieux que le compilateur ce qu'est l'objet que vous castez. Si le casting n'est pas exact, vous obtenez une exception.

Vous vous attendez peut-être à ce que le compilateur suive l'objet vers lequel les choses pointent et détermine si la référence est plausible. Le compilateur n'est pas si intelligent et se laisse facilement berner, voir cet extrait :

    int i = 1;
    System.out.println((Number)i);        
    Object o = i;
    System.out.println((String)i); // won't compile (primitive-to-ref-type cast)
    System.out.println((String)o); // compiles (thanks to autoboxing)

Le compilateur se préoccupe uniquement d'empêcher les conversions entre les primitives et les types de référence.

2voto

PermGenError Points 26936

Envisager de créer un objet Cottage (sous-classe) avec une référence Building (super classe)

Building b= new Cottage();
Cottage c = (Cottage) b;

Le code ci-dessus est légal, donc le compilateur ne saurait pas quel objet fait la variable de référence c au moment de l'exécution, le compilateur n'émettra donc pas d'erreur.

Pourquoi compile-t-il et lance-t-il ensuite une exception d'exécution (IllegalCastException) ?

BTW, il lance ClassCastException lorsque vous essayez de transformer un objet de la superclasse en objet de la sous-classe, et non en objet de la sous-classe. IllegalCastException .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X