Serious answers are given by actual benchmarks. For example, I used this jmh
-targeting code:
public class Benchmark1
{
static final List<Integer>[] lists = new List[10000]; static {
for (int i = 0; i < lists.length; i++) {
lists[i] = new ArrayList<Integer>(1);
lists[i].add(1);
}
}
static final Collection<Integer>[] colls = new Collection[lists.length]; static {
for (int i = 0; i < colls.length; i++) colls[i] = lists[i];
}
@GenerateMicroBenchmark
public long testNoDowncast() {
long sum = (long)Math.random()*10;
for (int i = 0; i < lists.length; i++) sum += lists[i].get(0);
return sum;
}
@GenerateMicroBenchmark
public long testDowncast() {
long sum = (long)Math.random()*10;
for (int i = 0; i < colls.length; i++) sum += ((List<Integer>)colls[i]).get(0);
return sum;
}
}
And jmh
provided the following results:
Benchmark Mode Thr Cnt Sec Mean Mean error Units
testDowncast thrpt 1 5 5 18.545 0.019 ops/msec
testNoDowncast thrpt 1 5 5 19.102 0.655 ops/msec
If you need interpretation, it is the following: there is no difference whatsoever.