I'm reading Effective Java 2nd edition from Joshua Bloch, item 25 (page 122). As you read further into the chapter, you get to a point where the author writes the following code :
// Naive generic version of reduction - won't compile!
static <E> E reduce(List<E> list, Function<E> f, E initVal) {
E[] snapshot = list.toArray(); // Locks list
E result = initVal;
for (E e : snapshot)
{
result = f.apply(result, e);
}
return result;
}
Then the author states that the compiler won´t compile this because you need to add an explicit cast to the line where is the assignment E[] snapshot = list.toArray();
, resulting on this E[] snapshot = (E[]) list.toArray();
, and after this you well get a warning saying that there is [unchecked] unchecked cast
.
Q1: I know that the book was taking into account changes up to Java 6 (and we are at Java almost 8 right now). However, I wrote the same method, a get the same error from the compile. This is because I am required to add the explicit cast. There is however no warning. So what is that warning about?
Q2: The author states the following method will work but it turns out that it isn't type safe.
With minor modifications, you could get it to throw a
ClassCastException
on a line that doesn't contain an explicit cast.
Okay, I understand that... but how can I get it to throw a ClassCastException
?
I leave this post with a ready to run example, if you want to check the things for yourselves:
import java.util.Arrays;
import java.util.List;
public class Main
{
public static void main(String[] args)
{
List<Integer> ints = Arrays.asList(10,20,30);
Integer result = reduce (ints,new Function<Integer>() {
@Override
public Integer apply(Integer arg1, Integer arg2)
{
return arg1 + arg2;
}
},0);
System.out.println(result);
}
static <E> E reduce(List<E> list, Function<E> f, E initVal)
{
E[] snapshot = (E[]) list.toArray(); // Locks list
E result = initVal;
for (E e : snapshot)
{
result = f.apply(result, e);
}
return result;
}
interface Function<T>
{
public T apply(T arg1, T arg2);
}
}