Impossible de lancer java.lang.Flotter pour flotter lors de l'utilisation de la classe.casting?
J'ai déjà une solution, mais je ne l'aime pas. Aussi, il serait bon de connaître vos pensées à ce sujet.
Vous voyez, elem.get
renvoie une Object
, qui va être un Float
dans le cas de x et y.
Ce code lève l'exception décrite dans le titre:
String names[] = { "x", "y", "src" };
Class types[] = { float.class, float.class, String.class };
for (int i = 0; i < names.length; i++)
{
if (elem.containsKey(names[i]))
{
par.add(types[i]);
arg.add(types[i].cast(elem.get(names[i])));
}
}
Le code est utilisé pour définir la liste des paramètres pour instancier un objet. Les paramètres et le nom de classe de l'objet sont définis dans un fichier de données externe (mais peu importe que).
La solution, quelque chose que je n'aime pas (parce qu'elle perd la flexibilité que j'essayais d'atteindre), a ceci dans le for:
if(types[i] == float.class)
{
float v = (Float)elem.get(names[i]);
arg.add(v);
} else
{
arg.add(types[i].cast(elem.get(names[i])));
break;
}
Une autre option changerait float.class
en Float.class
dans types
, mais je ne le ferai pas car ce code est utilisé pour instancier des objets qui ont des paramètres float
dans leurs constructeurs.
Merci!
1 answers
Comme le type de args
est un ArrayList<Object>
, vous n'évitez pas la boxe de toute façon:
// This code...
float v = (Float)elem.get(names[i]);
arg.add(v);
// Will actually be equivalent to:
float v = (Float)elem.get(names[i]);
Float boxed = v;
arg.add(boxed);
Si le but est d'appeler un constructeur par réflexion, alors vous allez avoir pour passer un Float
pour tous les paramètres float
- c'est comme ça que ça marche.
Donc fondamentalement, changez float.class
en Float.class
et tout devrait bien fonctionner. EDIT: Ah, sauf que la liste par
aura le mauvais type. Fondamentalement, vous voulez cast avec Float.class
, mais ajouter float.class
pour la liste des les types de paramètre.
Vous voulez probablement une carte des types primitifs aux types wrapper, comme ceci:
private static final Map<Class<?>>, Class<?>> PRIMITIVE_TYPE_MAP =
buildPrimitiveTypeMap();
private static Map<Class<?>>, Class<?>> buildPrimitiveTypeMap()
{
Map<Class<?>>, Class<?>> map = new HashMap<Class<?>>, Class<?>>();
map.put(float.class, Float.class);
map.put(double.class, Double.class);
// etc
return map;
}
Puis:
String names[] = { "x", "y", "src" };
Class types[] = { float.class, float.class, String.class };
for (int i = 0; i < names.length; i++)
{
if (elem.containsKey(names[i]))
{
par.add(types[i]);
// For primitive types, only box to the wrapper type
Class<?> castType = PRIMITIVE_TYPE_MAP.get(types[i]);
if (castType == null)
{
castType = types[i];
}
arg.add(castType.cast(elem.get(names[i])));
}
}
En fait, si vous croyez que les valeurs sont déjà du bon type, je soupçonne que vous pouvez simplement faire:
arg.add(elem.get(names[i]));
Après tout, vous passez simplement à un type particulier, puis vous perdez à nouveau ces informations de type... l'utilisation de l'appel cast
vérifie cependant que les types d'exécution sont corrects, vous pouvez donc le conserver pour que la raison.