简体   繁体   English

使用泛型的Class.cast使用ClassCastException

[英]ClassCastException using Class.cast using Generics

I am writing a generic method which will validate a property by trying a class.cast on it but I keep getting a ClassCastException 我正在编写一个通用方法,通过尝试对它的class.cast来验证属性,但我一直收到ClassCastException

... Class to Test ...要测试的课程

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;
}

... Test Class ...测试班

@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);
    }
}

The code at commented at MARKER is causing the ClassCastException. 标记在MARKER处的代码导致ClassCastException。

Any ideas much appreciated. 任何想法表示赞赏。

The Properties class is a Hashtable stores String objects, especially when you call setProperty . Properties类是一个Hashtable存储String对象,尤其是在调用setProperty You have added the String "3", not the integer 3 . 您添加了String “ 3”,而不是整数3 You are effectively attempting to cast "3" as an Integer , so that correctly throws a ClassCastException . 您实际上正在尝试将“ 3”强制转换为Integer ,以便正确抛出ClassCastException Try 尝试

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

Or if you want to have get return an Integer , then just use a Hashtable<String, Integer> , or even better, use a HashMap<String, Integer> . 或者,如果你get回报的Integer ,然后只使用一个Hashtable<String, Integer> ,或者甚至更好,使用HashMap<String, Integer>

Assuming that Properties here is java.util.Properties , the values are always String s. 假设此处的Propertiesjava.util.Properties ,则值始终为String

You should use the getProperty() method, rather than the get() method that happens to be visible from HashTable because this class was written back when the Java folks were less careful about composition versus inheritance. 您应该使用getProperty()方法,而不要使用从HashTable上可以看到的get()方法,因为Java伙计们在编写和继承方面不太谨慎时,会写回此类。

This Line 这条线

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

puts a java.lang.String in properties 在属性中放置一个java.lang.String

and You pass Integer.class to you generic method. 然后将Integer.class传递给您的通用方法。 So the ClassCastException is expected! 因此,可以期待ClassCastException

If you want to Test for Integer.class you have to put an Integer 如果要测试Integer.class ,则必须放置一个Integer

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

Note in the above line the use of put since the Properties class is extending Hashtable 注意,由于Properties类正在扩展Hashtable ,因此请在上一行中使用put

If your intention is to put a String and test for an Integer then you have to somehow parse that String to an Integer value 如果您打算放置一个String并测试一个Integer则必须以某种方式将该String 解析为一个Integer值

Thanks for your replies. 多谢您的回覆。 I realise the basic act of casting from String to Integer wasn't possible. 我意识到从String转换为Integer的基本操作是不可能的。 I was just trying to make the method slicker and do the conversion check for me. 我只是想让方法更流畅,并为我做转换检查。 I've just worked out the solution I was lookin using Reflection which is : 我刚刚制定了使用反射的查找解决方案,即:

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

ie Using the public constructor that takes the String.class (ie the String property value) 即使用采用String.class的公共构造函数(即String属性值)

Works a treat. 工作请客。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM