86 votes

Transfert de variables en Java

Je me demande si quelqu'un peut me dire comment fonctionne le casting ? Je comprends quand Je devrais le faire, mais je ne sais pas vraiment comment ça marche. En ce qui concerne les types de données primitifs, je comprends partiellement, mais lorsqu'il s'agit de couler des objets, je ne comprends pas comment cela fonctionne.

Comment un objet de type Object peut-il soudainement être converti en, disons.., MyType (juste un exemple) et ensuite obtenir toutes les méthodes ?

0 votes

Lecture suggérée : Héritage

0 votes

187voto

berry120 Points 21945

Le casting en Java n'est pas magique, il s'agit de dire au compilateur qu'un objet de type A est en fait de type B plus spécifique, et donc d'avoir accès à toutes les méthodes de B que vous n'auriez pas eu autrement. Vous n'effectuez aucune sorte de magie ou de conversion lorsque vous effectuez un casting, vous dites essentiellement au compilateur "faites-moi confiance, je sais ce que je fais et je peux vous garantir que cet Objet à cette ligne est en fait un <Insérer le type de cast ici>". Par exemple :

Object o = "str";
String str = (String)o;

Ce qui précède est bien, pas magique et tout va bien. L'objet stocké dans o est en fait une chaîne de caractères, et nous pouvons donc le convertir en une chaîne de caractères sans aucun problème.

Il y a deux façons dont ça pourrait mal tourner. Premièrement, si vous effectuez un casting entre deux types dans des hiérarchies d'héritage complètement différentes, le compilateur saura que vous êtes stupide et vous arrêtera :

String o = "str";
Integer str = (Integer)o; //Compilation fails here

Deuxièmement, s'ils se trouvent dans la même hiérarchie mais que leur distribution n'est toujours pas valide, alors une ClassCastException seront lancées au moment de l'exécution :

Number o = new Integer(5);
Double n = (Double)o; //ClassCastException thrown here

Cela signifie essentiellement que vous avez violé la confiance du compilateur. Vous lui avez dit que vous pouvez garantir que l'objet est d'un type particulier, et il ne l'est pas.

Pourquoi avez-vous besoin d'un casting ? Eh bien, pour commencer, vous n'en avez besoin que lorsque vous passez d'un type plus général à un type plus spécifique. Par exemple, Integer hérite de Number Ainsi, si vous souhaitez enregistrer un Integer en tant que Number alors il n'y a pas de problème (puisque tous les nombres entiers sont des nombres). Cependant, si vous voulez faire l'inverse, vous avez besoin d'un casting - tous les nombres ne sont pas des nombres entiers (en plus d'Integer, nous avons Double , Float , Byte , Long ) Et même s'il n'y a qu'une seule sous-classe dans votre projet ou dans le JDK, quelqu'un pourrait facilement en créer une autre et la distribuer, donc vous n'avez aucune garantie même si vous pensez que c'est un choix unique et évident !

En ce qui concerne l'utilisation du casting, on en voit encore le besoin dans certaines bibliothèques. Avant Java-5, il était fortement utilisé dans les collections et diverses autres classes, puisque toutes les collections fonctionnaient en ajoutant des objets et en rejetant le résultat obtenu dans la collection. Cependant, avec l'avènement des génériques, une grande partie de l'utilisation du casting a disparu - il a été remplacé par les génériques qui fournissent une alternative beaucoup plus sûre, sans le potentiel pour les ClassCastExceptions (en fait, si vous utilisez les génériques proprement et qu'il compile sans avertissements, vous avez la garantie que vous n'aurez jamais une ClassCastException).

7voto

sandrstar Points 5237

En fait, le casting ne fonctionne pas toujours. Si l'objet n'est pas un instanceof la classe dans laquelle vous le lancez, vous obtiendrez une ClassCastException au moment de l'exécution.

5voto

Christophe Roussy Points 2347

Supposons que vous vouliez lancer un String à un File (oui, cela n'a pas de sens), vous ne pouvez pas le lancer directement parce que la fonction File n'est ni un enfant ni un parent de la classe String (et le compilateur se plaint).

Mais vous pourriez lancer votre String a Object car un String est un Object ( Object est le parent). Vous pouvez alors transformer cet objet en un File parce qu'un fichier est un Object .

Ainsi, toutes vos opérations sont "légales" du point de vue du typage au moment de la compilation, mais cela ne signifie pas qu'elles fonctionneront au moment de l'exécution !

File f = (File)(Object) "Stupid cast";

Le compilateur l'autorisera même si cela n'a pas de sens, mais il se plantera à l'exécution avec cette exception :

Exception in thread "main" java.lang.ClassCastException:
    java.lang.String cannot be cast to java.io.File

3voto

asgs Points 2083

L'intégration d'une référence ne fonctionnera que si c'est une référence de type instanceof ce type. Vous ne pouvez pas lancer des références aléatoires. En outre, vous devez lire davantage sur Casting Objects .

par exemple

String string = "String";

Object object = string; // Perfectly fine since String is an Object

String newString = (String)object; // This only works because the `reference` object is pointing to a valid String object.

3voto

yegor256 Points 21737

La bonne méthode est la suivante :

Integer i = Integer.class.cast(obj);

La méthode cast() est une alternative beaucoup plus sûre au moulage au moment de la compilation.

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