0

我想编写通用代码来解析用户输入并将其与类数组进行比较,然后相应地转换输入。IE:

  1. 对象[] paramTypes = { String.class, String.class, Integer.class }
  2. Object[ ] userInput = { "playerName1", "targetPlayerName", "5" } //5 是一个字符串
  3. 用户输入的每个 String 都被强制转换为 paramTypes 中的相应类。
  4. 最后,转换后的词被放入另一个 Object[ ] castedUserInput 供以后使用。

    for(int i = 0; i<userInput.length; i++)
      castedUserInput[i] = paramTypes[i].cast(userInput[i]);
    
问题:

一旦 paramTypes[i] 为 Integer.class 并且执行了强制转换,就会发生 ClassCastException。该异常的文档内容如下:

ClassCastException:抛出以指示代码已尝试将对象强制转换为它不是实例的子类

因此,(Object)"5"(为什么这不起作用?)和 "5" 都不能转换为 Number 的子类。

现在我明白 Number 和 String 都是 object 的子类,但除此之外彼此不相关。我正在安装 JDK7 以查看NumberClassCastException的源代码,但我怀疑这对了解我只编程了大约一年并且对 java 编译器和虚拟的内容缺乏透彻理解会有很大帮助机器正是在这里做的。

有人可以帮我吗?

PS:当然可以使用一些 if 子句,然后使用 Integer.parseInt(userInput[i])、Long.parseLong(userInput[i]) 等,但这不是最有效的解决方案,对吧?

4

2 回答 2

1

正如您所描述的那样,您会得到类转换异常,因为输入的类型是String,并且String不能转换为Integer。您应该考虑输入转换为预期的参数类型,而不是强制转换。为此目的有一些框架,但如果您只有有限数量的可能类型,您可以自己编写一些东西。这Integer/Long.parseInt将是一种解决方案。

于 2013-04-28T21:33:07.847 回答
1

正如您正确指出的那样,这里的问题是字符串“5”被转换为整数。由于 Integer 不是 String 的子类,JVM 在运行时抛出 ClassCasrException。Integer 和 String 都是 Object 的子 cklsses,因此将 String 和 Integer 值转换为 Object 是安全的(就像在 Object 数组中存储字符串或整数时所做的那样)。

一种解决方法是使用:

for(int i = 0; i<userInput.length; i++)
  castedUserInput[i] = safeCast(paramTypes[i], userInput[i]);

您可能在哪里safeCast()使用您提到的 if 子句解析为 ints、longs 等进行转换。另一种更通用的方法是使用反射并调用带有 String 参数的构造函数。大多数具体的 Number 类(Byte、Double、Float、Integer、Long、Short)都支持此类构造函数,因此您应该熟悉 Number 类。对于自定义类,您将需要有一个带有单个 String 参数的构造函数。这是使用反射并依赖于将传递的值作为参数的构造函数的解决方案:

public static Object safeCast(Class paramType, Object value)
        throws NoSuchMethodException, IllegalAccessException,
        InvocationTargetException, InstantiationException {
    if (value == null) {
        return null;
    }
    final Class<?> valueClass = value.getClass();
    if (paramType.isAssignableFrom(valueClass)) {
        return value;
    }
    final Constructor theConstructor = paramType.getConstructor(valueClass);
    return theConstructor.newInstance(value);
}
于 2013-04-28T21:34:29.073 回答