Поскольку тип args
является ArrayList<Object>
, вы все равно не избегаете бокса:
// 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);
Если цель заключается в том, чтобы вызвать конструктор с помощью отражения, то вы собираетесь иметь для передачи Float
для любых float
параметров - вот как это работает.
Так что в принципе измените float.class
на Float.class
, и все должно работать нормально. РЕДАКТИРОВАТЬ: Ах, за исключением того, что список par
будет иметь неправильный тип. Обычно вы хотите приведение с Float.class
, но добавление float.class
в список типов параметров.
Возможно, вам нужна карта от примитивных типов к типам-обёрткам, например:
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;
}
Тогда:
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])));
}
}
На самом деле, если вы уверены, что значения уже имеют правильный тип, я подозреваю, что вы можете просто сделать:
arg.add(elem.get(names[i]));
В конце концов, вы просто приводите к определенному типу, а затем снова теряете информацию о типе ... с помощью вызова cast
выполняется проверка правильности типов времени выполнения, поэтому вы можете захотеть сохраните это по этой причине.