在码砖的时候用到了接口List的remove方法,该方法有两个overloading变种:
boolean remove(Object o);
E remove(int index);
突然想到,如果对于一个List<Integer>类型的对象,remove(1)调用的是哪个方法呢?
这个问题主要涉及三个概念以及他们之间的关系:overloading,type promotion和box&unbox。让我们逐一分析。
overloading
Overloading是指如果多个方法有相同的方法名但是参数不同。【1】
“参数不同”有三种形式【2】:
- 参数列表中参数的个数不同。
class DisplayOverloading
{
public void disp(char c)
{
System.out.println(c);
}
public void disp(char c, int num)
{
System.out.println(c + " "+num);
}
}
class Sample
{
public static void main(String args[])
{
DisplayOverloading obj = new DisplayOverloading();
obj.disp('a');
obj.disp('a',10);
}
}
Output:
a
a 10
- 参数的类型不同
class DisplayOverloading2
{
public void disp(char c)
{
System.out.println(c);
}
public void disp(int c)
{
System.out.println(c );
}
}
class Sample2
{
public static void main(String args[])
{
DisplayOverloading2 obj = new DisplayOverloading2();
obj.disp('a');
obj.disp(5);
}
}
Output:
a
5
- 参数的顺序不同
class DisplayOverloading3
{
public void disp(char c, int num)
{
System.out.println("I’m the first definition of method disp");
}
public void disp(int num, char c)
{
System.out.println("I’m the second definition of method disp" );
}
}
class Sample3
{
public static void main(String args[])
{
DisplayOverloading3 obj = new DisplayOverloading3();
obj.disp('x', 51 );
obj.disp(52, 'y');
}
}
Output:
I’m the first definition of method disp
I’m the second definition of method disp
编译器会通过比对调用时传入的参数和方法定义中的方法头决定调用哪个方法。而这一过程不得不考虑java的其他两个特性:Conversions and Promotions和box&unbox。
Conversions and Promotions
Conversions and Promotions有多种形式【3】
例如:
Widening Primitive Conversion是指一个size比较小的类型被自动转为size较大的类型
-
byte
toshort
,int
,long
,float
, ordouble
-
short
toint
,long
,float
, ordouble
-
char
toint
,long
,float
, ordouble
-
int
tolong
,float
, ordouble
-
long
tofloat
ordouble
-
float
todouble
class Demo{
void disp(int a, double b){
System.out.println("Method A");
}
void disp(int a, double b, double c){
System.out.println("Method B");
}
public static void main(String args[]){
Demo obj = new Demo();
/* I am passing float value as a second argument but
* it got promoted to the type double, because there
* wasn't any method having arg list as (int, float)
*/
obj.disp(100, 20.67f);
}
}
Output:
Method A
Widening Reference Conversion 是指将对类型S的索引转为对类型T的索引,其中S是T的子类。
public class TestInh {
public static void main(String...strings){
m1(Integer.valueOf(1));
}
private static void m1(Object o){
System.out.println("Object");
}
}
Output:
Object
box&unbox
严格来说,box&unbox也是Conversions and Promotions的一种。box是指将int一类的primitive 类型转为一个Integer对象,unbox是box的逆操作,也就是将Integer对象转为int。
public class TestInh {
public static void main(String...strings){
m1(1);
}
private static void m1(Integer io){
System.out.println("Integer");
}
}
Output:
Integer
Conversions and Promotions和box&unbox的优先级
Widening Primitive/Reference Conversion > box&unbox
- 对于primitive type,
public class TestInh {
public static void main(String...strings){
m1(1);
}
private static void m1(long l){
System.out.println("long");
}
private static void m1(Integer io){
System.out.println("Integer");
}
}
output:
long
- 对于object type,
public class TestInh {
public static void main(String...strings){
m1(Integer.valueOf(1));
}
private static void m1(int i){
System.out.println("int");
}
private static void m1(Object o){
System.out.println("Object");
}
}
output:
Object
结论
如果定义了List<Integer>类型的对象,那么remove(1)调用的是:
E remove(int index);
remove(Integer.valueOf(1))调用的是:
boolean remove(Object o);
【1】core java chapter 4 collection
【2】Method Overloading in Java with examples
【3】Conversions and Promotions
网友评论