Comment “dynamique” cast une instance du type d'Objet dans son type de données spécifique?
public Object foo(int opt){
if (opt == 0) return new String();
else if (opt == 1) return new Integer(1);
else if (opt == 2) return new Double(1);
else if ...
.. and many more
}
public void doSomething(String s){..}
public void doSomething(Integer i){..}
public void doSomething(Double d){..}
... and many more doSomething method
public static void main(String[] args){
...
Object o = foo(x); //x is a value obtained during runtime, e.g. from user input
//now I want to call doSomething method
//(1)
if (o instanceof String) doSomething((String) o);
else if (o instanceof Integer) doSomething((Integer) o);
else if (o instanceof Double) doSomething((Double) o);
...
//(2)
}
Est-il une meilleure façon de simplifier les déclarations incluses par (1) ... (2)?
Java Réflexion aider?
OriginalL'auteur Pahlevi Fikri Auliya | 2011-04-11
Vous devez vous connecter pour publier un commentaire.
La meilleure façon de gérer cela de façon efficace et propre est d'avoir foo retour d'un titulaire de la classe de l'objet.
OriginalL'auteur Peter Lawrey
Ici, le problème peut être celui de la séparation des préoccupations. Java est un langage orienté objet, et il peut aider à résoudre le problème dans une méthode orientée objet. Dans ce cas, vous pourriez vous demander pourquoi principal devrait soins de quel type d'Objet o est. Au lieu de cela, vous pourriez envisager d'avoir un ensemble de classes, dont chacun sait comment faire quelque chose à sa manière.
Votre foo() la méthode devient une usine, et à partir de ce point transfère vous n'avez plus besoin de se soucier de ce genre de Chose a été renvoyée par foo.
OriginalL'auteur Brandon Yarbrough
Fondamentalement, vous voulez résolution de surcharge effectué au moment de l'exécution - vous n'allez pas être en mesure de le faire très simplement.
Dans certains cas, la modèle visiteur peut aider, mais je ne pense pas qu'il serait ici. Je pense que vous êtes coincé avec soit le code que vous avez obtenu ici, ou de réflexion. Je n'ai jamais été aussi vif sur le modèle visiteur comme certains de mes collègues - il se sent toujours un peu confus, mais il vaut la peine de la pensée.
Pourrait vous faire
foo
appeler le droitdoSomething
surcharge au lieu de simplement retourner la valeur? C'est le morceau de code qui sait ce qui est en cours de construction - si vous pouviez passer un objet pour appelerdoSomething
sur avec la surcharge, vous finirais avec le type spécifique de la logique en un seul endroit.Dans Java 7, il est possible que invokedynamic sera utile dans ce genre de situation, certainement le
dynamic
type en C# 4 pourrait l'aider, mais je n'ai pas regardé invokedynamic assez pour le dire.invokedynamic
bytecode. J'aimerais avoir tort sur ce point, cependant.Ah, je pensais que c'était l'un des projets de changements de langue dans Java 7. J'ai perdu la trace de ce qui est et ce qui est sur, pour être honnête...
OriginalL'auteur Jon Skeet
Réflexion Java aide un peu, mais il y a une pièce manquante de données. Aussi, la réflexion typiquement génère de NOMBREUSES vérifié les exceptions que vous aurez besoin de l'attraper. (J'ai inclus une liste d'après le code)
Quel est l'objet qui détient la "doSomething" méthodes? Dans cet exemple, j'utilise le nom de la variable "someObject" pour représenter l'objet de la tenue de la "doSomething" la méthode. Vous avez besoin de la remplacer par quelque chose de plus sensés.
Aussi, juste un avertissement, ce ne sera pas attraper les types dérivés, de sorte que si la définition de la méthode ne correspond pas au type de donnée, vous obtiendrez une méthode pas trouvé exception.
Avertissement: Vous devez traiter avec les exceptions suivantes lors de l'utilisation de la réflexion de cette façon: (Ce n'est pas inhabituelle liste d'ailleurs, la réflexion est en général très bruyant en termes d'exceptions)
OriginalL'auteur SplinterReality
Il ne ferait aucun sens de le faire en Java. Java est statiquement typé, si vous étiez la lancer dynamiquement, vous DEVEZ avoir une instruction switch pour le faire afin d'appeler les différentes méthodes sur les différents objets.
Exemple, si vous avez une chaîne ou un entier (int) et que vous souhaitez "Dynamique" de voter pour elle (sans interrupteur), l'opération peut-on faire pour les deux d'entre eux qui ne nécessite pas de code différent.
Je suppose que je suis en train de dire que si vous avez à jeter parce que vous voulez quelque chose qui est différent sur les deux objets (une méthode différente), alors comment pouvez-vous accéder à cette autre méthode sans un commutateur?
La seule exception pourrait être intrinsèque des variables-pour ceux que vous voulez génériques, mais à l'aide de variables intrinsèques à l'extérieur des classes est une mauvaise idée de toute façon.
Oh, Ce que vous avez probablement voulez vraiment est d'avoir toutes les classes implémentent la même interface--alors vous n'avez pas exprimés.
Casting devrait être extrêmement rare.
OriginalL'auteur Bill K