开发者

Integer and int duality?

Can someone explain me this

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

when I used

 list.remove(1);

then 1st element got remove开发者_高级运维d

 list.remove(new Integer("1"));

then 2nd element got removed.

so, can you explain behavior of auto boxing and unboxing in above senario

when new A().a(new Integer("1"));

executed on,

public class A {
    public void test(Integer i) {} //1
    public void test(int i) {} //2
    public void test(Object o) {}//3
} 

method 1 go executed

public class A {
    public void test(int i) {} //2
    public void test(Object o) {}//3
} 

method 3 got executed


Basically overload resolution will prefer an Object parameter over an int parameter when presented with an Integer argument. (It will prefer an overload with an int parameter over Object or Integer when presented with an int argument, of course.)

From JLS section 15.12.2 (with discussion snipped):

The process of determining applicability begins by determining the potentially applicable methods (§15.12.2.1). The remainder of the process is split into three phases.

Discussion

The purpose of the division into phases is to ensure compatibility with older versions of the Java programming language.

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.

The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing and unboxing.

As Integer is implicitly convertible to Object, overload resolution succeeds in the first phase, so never gets as far as considering an unboxing conversion.

If that doesn't explain everything to your satisfaction, please comment on which bit remains puzzling for you.


 list.remove(1);

here 1 is index, and not the object, so whatever object is present at index 1, will be deleted

 list.remove(new Integer("1"));

Here its the object Integer(1), that will be deleted


This is all explained and specified in tha Java Language Specification.


The problem is that new Integer(2) is an object but 2 isn't

remove(1) removes the element with index 1

remove (new Integer(2) removes the Objecte equal to new Integer(2) (two different methods)

If you add(1) Java needs an object since there is no add(int) and performs Outboxing.

The same happens probably in your second example though it seems it got a little mixed up (text doesn't fit code).

The crucial part is: Unboxing of an Integer is only performed when an Integer can not be used, i.e. there is no use for Integer, Number or Object, but int can be used.


Overload resolution uses the best matching candidate. In the first case, you are passing Integer and there is a signature test(Integer) so that gets called (exact type match).

In the second case you pass Integer, and the two possible candidates are test(int) and test(Object). In this case the language defines the Object upcast as a closer match than the int unboxing, so the Object version is selected.

There is a list of overload resolution conversions here. As you can see, reference widening is higher up than unboxing.


From the Java language specification:

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion,

...

This guarantees that any calls that were valid in older versions of the language are not considered ambiguous as a result of the introduction of variable arity methods, implicit boxing and/or unboxing.


List provides to methods:

public boolean remove(Object o)   // removes the first occurence of this object
public boolean remove(int i)      // removes object stored at index i

If we do a list.remove(new Integer(1)) then the best match for this call is the first method (remove the object).


There are two remove functions specified on a List:

  • List.remove(int)
  • List.remove(Object)

Although Java does perform autoboxing (and I believe it would, if the List.remove(int) method didn't exist), the idea here is determining which method to call. Since there is a valid operation with a primitive int, that's going to be called before any autoboxing happens.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜