DaveH
DaveH

Reputation: 7335

Specify the Type on a Class Object

The following code calls the setProperty method on a Camel Exchange

List<Message> list = oldExchange.getProperty("p",List.class);

The intention is that I retrieve a List object that I have previously stored against the Exchange instance.

As this code stands, I get a compiler warning ( Type safety: The expression of type List needs unchecked conversion to conform to List ).

I know I can make this go away by adding the @SuppressWarnings("unchecked") annotation, but is there a way that I can fix it by changing the declaration of List.class?

The getProperty method has the following signature <T> T getProperty(String name, Class<T> type)

Upvotes: 5

Views: 419

Answers (2)

Adam Michalik
Adam Michalik

Reputation: 9945

Unfortunately, this cannot be done - there is no class literal expression for generic types.

If you have a lot of such calls in your code, you may want to create a utility method to suppress the warnings in one place only:

@SuppressWarnings("unchecked")
static <T> T  myGetProperty(String name, Class<?> type) {
    return (T) getProperty(name, type);
}

Then this call comes without a warning:

List<String> listOfStrings = myGetProperty("a", List.class);

However, you need to keep in mind that it is indeed unchecked so you can't be sure that the elements of the list are strings.

Upvotes: 3

Tagir Valeev
Tagir Valeev

Reputation: 100169

Here unfortunately your cast cannot be safe, because while you know that returned object has the List type, you cannot be sure that all the elements of this list has the Message type. So you may get an unexpected ClassCastException much later, when you write something like Message m = list.get(0);

To make your code robust you have to check all the existing list elements, then you can do the unchecked cast like this:

public static <T> List<T> checkElements(List<?> list, Class<T> elementClass) {
    for(Object e : list) {
        elementClass.cast(e); // throw CCE on wrong element
    }
    @SuppressWarnings("unchecked")
    List<T> result = (List<T>)list;
    return result;
}

The @SuppressWarnings is still necessary inside this method, but it's "library" method, so it's ok here. However in business code you may use now:

List<Message> list = checkElements(oldExchange.getProperty("p",List.class), Message.class);

The disadvantage of such approach is that it takes some time to check the type of every element. If you 100% sure that you have the correct list, then just use @SuppressWarnings in your original code.

Upvotes: 1

Related Questions