-2

if List<Object> contains List<Integer> than it is perfect But how could java allows the test of List<Integer> containing List<Object> without throwing any compile-time error.

TestCase-1

Object obj = "one";
List<Object> objs = Arrays.<Object>asList("one", 2, 3.14, 4);
List<Integer> ints = Arrays.asList(2, 4);
assert objs.contains(obj); //Statement 1
assert objs.containsAll(ints); //Statement 2
assert !ints.contains(obj); //Statement 3 
assert !ints.containsAll(objs); //Statement 4

In above case statement 3 & 4 compile & run Successfully.So my doubts are :

  1. How can Statement 3 & 4 be run as there should be a compile-time error?
  2. Is it an error or there is some reason for providing such a contradictory support ?
Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
Prateek
  • 12,014
  • 12
  • 60
  • 81

3 Answers3

1

How can Statement 3 & 4 be run as there should be a compile-time error?

This is because contains(object) will take any object.

Is it an error or there is some reason for providing such a contradictory support ?

Before Java had generics you could call contains(Object) and so you can today using code that was written before generics.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • 1
    it means the above support is for backward compatibility. – Prateek Sep 03 '13 at 12:23
  • @Prateek In short, yes. But since that can mean a lot of things (excuse a lot of sins) I prefer to give some explanation if I can ;) – Peter Lawrey Sep 03 '13 at 12:27
  • @Prateek Those `Object` methods are one of the worst features of Collections and you can regularly find bugs that result from incomplete refactoring. :( [JSR-14](http://jcp.org/en/jsr/detail?id=14) states the source backwards compatibility part but it does not say whether they where thinking about adding typesafe versions + keep the old ones deprecated for compatibility. I would have preferred that. – zapl Sep 03 '13 at 12:38
  • @zapl can you mention the same thing in answer. also can you correct my question, if something wrong in language – Prateek Sep 03 '13 at 12:40
0

This unfortunate decision had to be made for backward compatibility with Java 1.4 compiled code.

Without this, the 1.4 code would not have run in 1.5 environment at all without full recompile.

Alexander Pogrebnyak
  • 44,836
  • 10
  • 105
  • 121
0

From the JDK sources, java.util.List has the methods:

boolean contains(Object o); containsAll(Collection<?> c)

So there isn't any compile time issue (any input you use in your code is correct).

As these methods don't use generics, there must be a reason deep inside the JDK maybe for back compatibility in some implementations / uses of List.

As you know, generics are only compile-time checks in Java so the runtime is just the same as if you were using List<Object>.

zenbeni
  • 7,019
  • 3
  • 29
  • 60