仅当给定类名作为该类型的字符串时,转换为未知类型

时间:2009-01-26 18:46:04

标签: java class casting

我目前拥有一个对象列表(使用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参数为我提供正确的类型?

5 个答案:

答案 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)似乎有点可疑对象),但你显然想调用特定于每种不同类型的操作......

这个系列有什么意义?你保留在其中的实例是否有任何共同点 - 你可以将它们转换成任何常见的超类型吗?