Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's wrong with the unchecked cast?

Tags:

java

I'm reading J. Bloch's effective Java and now I'm at the arrays vs lists section. Here is an example of unchecked cast he provided:

interface Function<T> {
    T apply(T arg1, T arg2);
}

public class Main{
    public static void main( String[] args ){
        Function<String> f = null;
        List<String> str = Arrays.asList("asd");
        //staff
        reduce(str, f, ""); //E's deduced to String. Where is type-unsafe?
    }
    static <E> E reduce(List<E> list, Function<E> f, E initVal) {
        E[] snapshot = (E[]) list.toArray(); // Unchecked cast
        E result = initVal;
        for (E e : snapshot)
            result = f.apply(result, e);
        return result;  
    }
}

He said that the method is not type-safe and we can easily get the ClassCastException. But I don't see how. Where's the type-unsafe, the type variable E will always be deduced to the appropriate type so we're no worried about class-cast-exeption.

Couldn't you give an example with throwing ClassCastException?

like image 307
St.Antario Avatar asked Jul 01 '15 08:07

St.Antario


People also ask

How do I fix unchecked unchecked cast?

If we can't eliminate the “unchecked cast” warning and we're sure that the code provoking the warning is typesafe, we can suppress the warning using the SuppressWarnings(“unchecked”) annotation. When we use the @SuppressWarning(“unchecked”) annotation, we should always put it on the smallest scope possible.

What is an unchecked cast?

Unchecked cast means that you are (implicitly or explicitly) casting from a generic type to a nonqualified type or the other way around.

What is unchecked warning?

An unchecked warning tells a programmer that a cast may cause a program to throw an exception somewhere else. Suppressing the warning with @SuppressWarnings("unchecked") tells the compiler that the programmer believes the code to be safe and won't cause unexpected exceptions.

How do you stop unchecked cast Kotlin?

Adding @Suppress("UNCHECKED_CAST") (also possible through IDEA's Alt + Enter menu) to any of statement, function, class and file should help.


1 Answers

There's no compile-time guarantee that list.toArray() will return the array of type E[]. Moreover it almost always returns an array of type Object[]. Thus depending on the later usage of this array you may have a ClassCastException. For example, consider the following code:

public static void main( String[] args ){
    List<String> str = Collections.singletonList("asd");
    String[] array = test(str);
}

static <E> E[] test(List<E> list) {
    E[] snapshot = (E[]) list.toArray(); // Unchecked cast
    return snapshot;
}

Here you return this E[] array and the receiver expects that String[] array is returned. But actually it's Object[] array, thus you will get the ClassCastException in main method after the returned generic type is implicitly cast to the String[].

In your code you can be sure that the array is used in safe way. But compiler is not smart enough to make this analysis, so it just warns you.

like image 164
Tagir Valeev Avatar answered Sep 26 '22 07:09

Tagir Valeev