2

I noticed strange situation:

consider these code snippets:

1

    List<Integer> list= new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.remove(new Integer(1));

out:

[2, 3]

2

    List<Integer> list= new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.remove(1);
    System.out.println(list);

out:

[1, 3]

After comparison of first two snippets I thought that in first case code works so thanks to integers pool

but following snippet reassured me:

3

    List<Integer> list= new ArrayList<>();
    list.add( new Integer(12345));
    list.add(2);
    list.add(3);
    list.remove(new Integer(12345));
    System.out.println(list);

out:

[2, 3]

Please explain what rules does ArrayList use to detect object or index?

gstackoverflow
  • 36,709
  • 117
  • 359
  • 710
  • 1
    `remove` takes an `int` or an `Object`. The compiler decides which method is the closest match. `Integer` is an `Object` so it calls [`remove(Object)`](http://docs.oracle.com/javase/7/docs/api/java/util/List.html#remove(java.lang.Object)), `1` is an `int` so it calls [`remove(int)`](http://docs.oracle.com/javase/7/docs/api/java/util/List.html#remove(int)). – Boris the Spider Mar 30 '14 at 21:34
  • @Boris the Spider because widening has higher priority? – gstackoverflow Mar 30 '14 at 21:38
  • 1
    Read [JLS §15.12.2](http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2) if you want to really understand what's going on. – Boris the Spider Mar 30 '14 at 21:41
  • There's no widening here. The two options the compiler has are: (1) treat `Integer` as an object, pass that to `remove(Object)`; or (2) auto-unbox the `Integer` to an `int`, pass that to `remove(int)`. The JLS says that the former is more specific and thus has precedence. It _could_ have been the other way around, in theory, but it isn't. (And it "can't" be for historical reasons, since autoboxing came relatively late in the game, so picking that as the closer option would have broken existing code that was passing `Integer`s in and expecting the `remove(Object)` method.) – yshavit Mar 30 '14 at 21:41
  • @yshavit Integer -> Object - it is widening) – gstackoverflow Mar 30 '14 at 21:44
  • Ah, so you're right. For some reason I thought the JLS called it something else, and reserved widening only for primitives. But 5.1.5 clearly calls it a widening reference conversion. – yshavit Mar 30 '14 at 21:57

0 Answers0