【问题标题】:ClassCastException using Class.cast using GenericsClassCastException using Class.cast using Generics
【发布时间】:2013-03-26 20:11:26
【问题描述】:

我正在编写一个通用方法,该方法将通过在其上尝试 class.cast 来验证属性,但我不断收到 ClassCastException

...要测试的类

public <T> T get(Properties p, String propKey, Class<T> clazz) throws Exception {

    T val = null;

    Object propValue = p.get(propKey);

    if(propValue== null) {
        throw new Exception("Property (" + propKey + ") is null");
    }

    try {
        val = clazz.cast(propValue); // MARKER

    } catch(Exception e) {
        throw new Exception("Property (" + propKey + ") value is invalid value of type (" + clazz + ")", e);
    }



    return val;
}

...测试类

@Before
public void setUp() {
    propUtil = new PropUtil();
    properties = new Properties();
    properties.setProperty("test.int.prop", "3");
}

@Test
public void testGet() {

    try {

        assertEquals(new Integer(3), propUtil.get(properties, "test.int.prop", Integer.class));
    } catch (Exception e) {
        System.out.println(e);
    }
}

MARKER 处注释的代码导致 ClassCastException。

非常感谢任何想法。

【问题讨论】:

    标签: java class generics casting classcastexception


    【解决方案1】:

    Properties 类是一个Hashtable 存储String 对象,尤其是当您调用setProperty 时。您添加了String“3”,而不是整数3。您实际上是在尝试将“3”转换为Integer,以便正确地抛出ClassCastException。试试

    assertEquals("3", propUtil.get(properties, "test.int.prop", String.class));
    

    或者如果您想要get返回Integer,那么只需使用Hashtable&lt;String, Integer&gt;,或者更好的是,使用HashMap&lt;String, Integer&gt;

    【讨论】:

    • 谢谢。请在下面查看我的答案。
    【解决方案2】:

    假设这里的Propertiesjava.util.Properties,则值总是Strings。

    您应该使用getProperty() 方法,而不是恰好在HashTable 中可见的get() 方法,因为这个类是在Java 人员对组合与继承不太注意时写回的。

    【讨论】:

    • 是的。它们始终是字符串,但属性将包含字符串、整数和双精度数,因此我希望通用方法进行转换,如果实际值不可分配给类,则抛出异常。
    【解决方案3】:

    这条线

    properties.setProperty("test.int.prop", "3");
    

    在属性中放置一个java.lang.String

    然后您将Integer.class 传递给您的通用方法。所以ClassCastException是预期的!

    如果你想测试Integer.class,你必须输入一个整数

    properties.put("test.int.prop", 3);
    

    请注意在上一行中使用了put,因为Properties 类正在扩展Hashtable

    如果您的意图是放置一个String 并测试一个Integer,那么您必须以某种方式将该字符串parse 设置为一个整数值

    【讨论】:

    • setProperty 方法采用 String 作为值,而不是 int
    • 谢谢。请在下面查看我的答案。
    【解决方案4】:

    感谢您的回复。我意识到从 String 转换为 Integer 的基本行为是不可能的。我只是想让方法更流畅并为我做转换检查。我刚刚使用反射解决了我正在寻找的解决方案:

        Object propValue = p.get(propKey);
        Constructor<T> constructor = clazz.getConstructor(String.class);
        val = constructor.newInstance(propValue);
    

    即使用采用 String.class 的公共构造函数(即 String 属性值)

    工作是一种享受。

    【讨论】:

    • 不错的解决方法,如果没有具有该签名的构造函数,则会抛出 NoSuchMethodException 女巫,您似乎可以在代码中处理。
    猜你喜欢
    • 2022-06-03
    • 2022-07-07
    • 1970-01-01
    • 2011-06-14
    • 2013-04-14
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 2021-05-28
    相关资源
    最近更新 更多