我有一个类类型,我在字符串中有一个值:
Class<?> type = Integer.class // <-- in reality, that type is
// determined at runtime
String value = "3"; // <-- same here, actually read from a file
我的目标是实例化一个'type'的实例,并用'value'的值填充它...所以我有相当于
Integer i = new Integer(value);
唯一可行的方法是做一长串if语句:
if (type == Integer.class) {
// do this
}
还是有另一种聪明/正确的方法吗?可能的类类型可能完全不同,如整数/日期等...
EDIT1
这里有更多背景信息:
我有一个包含许多值的文件,这些值是不同数据类型实例的文本表示:
1|3.4|2011-08-24
在我的程序中,我得到了一个类类和一个方法,在编译时我都不知道。
我想在该类型的实例上调用该方法,并将文件中的值作为参数。但是对于那个我必须有相应的对象到该值,在示例中可以是Integer / int,float / double,Date。 我可以通过反射获得方法的形式参数的这些数据类型,但我不确定从字符串到对象的转换的最佳方法......
也许这个伪程序会搞清楚:
String[] values = getValuesFromFile;
Class<?> type = getType();
Method method = getMethod();
Class<?>[] formalParameterTypes = getMethodParameterTypes();
Object[] objects;
for(int i; i < values.length; i++)
objects[i] = convert(values[i],formalParameterTypes[i]);
method.invoke(objects);
答案 0 :(得分:1)
发明动态类加载和反射来解决这些问题。 E.g。
Class<?> type = Class.forName("MyClassName");
Object obj = type.newInstance();
现在,如果要在对象中设置字段,则有两个选项:
答案 1 :(得分:1)
如果您的类型仅限于原始数据类型的包装类,则所有类都具有静态valueOf(String)方法,该方法可用于解析String并返回有效实例。
我会使用反射来查找和调用方法并使用结果:
public static void main(String[] args) throws Exception {
int i = parse(Integer.class, "4711");
double d = parse(Double.class, "47.11");
boolean b = parse(Boolean.class, "true");
System.out.println(i);
System.out.println(d);
System.out.println(b);
}
public static <T> T parse(Class<T> type, String value) {
try {
return (T)type.getDeclaredMethod("valueOf", String.class).invoke(null, value);
}
catch(Exception e) {
throw new RuntimeException(e);
}
}
答案 2 :(得分:1)
根据我的理解,你想要这样的东西:
Object instance = createMagically(getClass(), getString());
其中getClass()
可能会返回Integer.class
而getString()
可能会返回值"42"
。但价值对Date.class
和"15 Apr 2011"
也是预期的。
您必须使用条件(if / else if),因为通常每种类型都有自己的转换规则。没有通用构造函数可以从String创建实例。
所以你可以实现这样的“工厂”方法:
public static Object createInstance(Class<?> type, String content) {
if (type.equals(Integer.class)) return new Integer(content);
else if // ...
return content; // just an idea for a default if the type can't be handled
}
然后,再次使用返回值,如果要确定实际类型,可能需要更多if / else if(if (value instancof Integer)
...)
所以,从我的观点来看 - 你有做了很多检查,但你可以隐藏实用程序类中的丑陋魔法。
答案 3 :(得分:0)
使用JSON,您可以在运行时将字符串转换为对象,而不必知道开头的原始类型。
答案 4 :(得分:0)
如果值只有字符串表示,您可以这样做:
String typeName = ...
String value = ...
Class<?> type = Class.forName(typeName);
Constructor<?> constructor = type.getConstructor(String.class);
Object instance = constructor.newInstance(value);
// cast the instance to actual class