0

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 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.

Any ideas much appreciated.

4 Answers 4

3

The Properties class is a Hashtable stores String objects, especially when you call setProperty. You have added the String "3", not the integer 3. You are effectively attempting to cast "3" as an Integer, so that correctly throws a 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>.

Sign up to request clarification or add additional context in comments.

Comments

2

Assuming that Properties here is java.util.Properties, the values are always Strings.

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.

1 Comment

Yes. They are always String but the properties will contain String, Integers and Doubles so I want the generic method to do the conversion and throw an exception if the actual value is not assignable the class.
1

This Line

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

puts a java.lang.String in properties

and You pass Integer.class to you generic method. So the ClassCastException is expected!

If you want to Test for Integer.class you have to put an Integer

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

Note in the above line the use of put since the Properties class is extending Hashtable

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

1 Comment

The setProperty method takes a String for the value, not an int.
0

Thanks for your replies. I realise the basic act of casting from String to Integer wasn't possible. 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);

i.e Using the public constructor that takes the String.class (i.e. the String property value)

Works a treat.

1 Comment

Nice workaround, and if there is no constructor with that signature a NoSuchMethodException is thrown witch you seem to handle in your code.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.