我目前拥有一个对象列表(使用Java 1.3),让我们说我想将从list.get(i)返回的一个对象转换为一种类型,我只知道类的名称为一个字符串。基本上,我该怎么做 对象o =(classname)list.get(i);其中className是className的String变量。
我以为我可以使用(Class.forName(className))list.get(i),但我收到语法错误,声称我忘记了分号。
不幸的是,由于我使用的是Java 1.3,因此我无法访问Class.cast(Object)方法。
在Java 1.3中转换为其他类型时使用的类的名称是什么?是否有一些方法可以通过类名的String参数为我提供正确的类型?
答案 0 :(得分:10)
当你所做的就是将结果分配给对象时,什么是转换点? 如果它没有实现接口/扩展,或者是类,或者如果它没有做任何事情,那么你将实现的只是异常。
为此简单起见:
public static boolean IsInstance(object x, String className)
{
Class cls = Class.forName(className);
return cls.isInstance(x);
}
足够(且更清洁)
如果您使用反射来获得类似于
的类的字段/方法答案 1 :(得分:5)
不,你不能在大多数语言中这样做。
原因是要编译的类型必须在编译时知道,而不是在运行时(这是你想要做的)。
如果你考虑一下,这是有道理的,因为假设变量可以是任何类型名称,你应该如何访问各个成员?你不能,除非它们是在所有实例实现的基类型/接口中定义的,在这种情况下你应该只使用它。
答案 2 :(得分:2)
需要出现这种情况的一种情况是使用遗留系统强制执行类型安全。例如,假设您有一个像Hibernate这样的持久性系统,它提供了来自“finder”方法的原始List
结果。将此原始List
转换为参数化类型将导致未经检查的警告,并且如果List包含错误类型的对象,则可以在某些远程相关代码中在未指定的时间引发ClassCastException
。最好使用OP建议的机制预先验证列表的内容。
这是Java 1.3版本(没有泛型):
private static void checkType(Collection objs, String className)
throws ClassNotFoundException
{
Class clz = Class.forName(className);
Iterator i = objs.iterator();
while (i.hasNext()) {
Object obj = i.next();
if (!clz.isInstance(obj)) {
throw new ClassCastException();
}
}
}
在Java 5及更高版本中,使用泛型,您可以使用Class.cast()
方法执行类似的操作来验证集合的内容,从而证明使用SuppressWarnings注释是正确的。在我们的审核过程中,如果没有一些“证明”它是安全的,就会将警告作为错误提交。
答案 3 :(得分:1)
我认为你真的想写下面的内容,而不是在左侧使用Object
。否则,它实际上只是检查列表中的对象是否是正确的类型。
ClassName o = (classname)list.get(i);
嗯,Java是静态类型的。你不可能给它一个字符串,它会给你相应的静态类型,这样你就可以不进行投射。即使使用泛型和Class<T>.cast
,转换目标类型也不是由字符串给出,而是由编译时已知的泛型类型参数T
给出。您必须手动转换为正确的类型,或继续使用最常见的类型(在您的情况下可能是对象)。
如果你执行Class.forName(className)
,它会返回一个Class
类型的对象,其中包含有关运行时类型的信息,以便它可以让你做
Class.forName("my.stuff.MyClass").newInstance()
但演员想要一个类型 - 而不是某种类型的对象。这就是编译器告诉你该代码有问题的原因。
由Object
返回的引用的静态类型。这很重要:引用的对象的动态类型,以及指向该对象的引用的静态类型。对象的动态类型是可以由字符串“控制”的(通过使用Class.forName
),但是在编译时必须执行的引用的静态类型,这是(只是为了给出)用于选择彼此重载的函数的示例)不能由字符串确定。
答案 4 :(得分:0)
问题已经是answered,但我想补充一点,你应该有一个List,你可以保存几种不同类型的对象(在这种情况下, any)似乎有点可疑对象),但你显然想调用特定于每种不同类型的操作......
这个系列有什么意义?你保留在其中的实例是否有任何共同点 - 你可以将它们转换成任何常见的超类型吗?