📅  最后修改于: 2020-03-31 01:27:02             🧑  作者: Mango
先决条件:方法重载,自动装箱和拆箱
在Java中,有两种类型的变量:原始类型和引用类型。将原始类型转换为对应的包装对象称为自动装箱,将包装对象转换为对应的原始类型称为拆箱。
自动装箱方法重载
在方法重载中,您可能会遇到签名采用引用类型或原始类型作为形式参数的情况。编译器首先搜索具有相同数据类型参数的方法。如果您使用包装器类Object作为实际参数,并且编译器未找到具有相同引用类型(即类或接口类型)的参数的方法,则它将开始搜索具有对应参数的基本数据类型方法。
// Java展示自动装箱
// 解析参数类型:
// a)引用 b)原始类型
import java.io.*;
public class Conversion
{
// 1.使用原始数据类型重载
public void method(int i)
{
System.out.println("原始的int形参 :" + i);
}
// 使用引用形参重载
public void method(Integer i)
{
System.out.println("引用为Integer的形参 :" + i);
}
// 2. overloaded method primitive formal argument
// and to be invoked for wrapper Object as overloaded method
// with wrapper object of same(Long) type as an argument is not
// available.
public void method(long i)
{
System.out.println("Primitive type long formal argument :" + i);
}
}
class GFG
{
public static void main (String[] args)
{
Conversion c = new Conversion();
// invoking the method with different signature.
c.method(10);
c.method(new Integer(15));
c.method(new Long(100));
// Using short will give, argument mismatch;
// possible lossy conversion from int to short
// c.method(new Short(15));
}
}
输出:
Primitive type int formal argument :10
Reference type Integer formal argument :15
Primitive type long formal argument :100
拓展方法重载
如果编译器未能找到与自动装箱相对应的任何方法,则它将开始搜索扩展后的原始数据类型的方法参数。
在下面的示例中,我们将使用具有原始数据类型与实际参数的数据类型相同的、带有原始(int)形式参数的重载方法。我们正在调用带有Long wrapper Object参数的另一种方法。编译器开始搜索具有相同引用类型(长包装类)的方法。由于没有方法具有Long包装器类的参数。因此,它搜索可以接受大于Long原始数据类型的参数作为参数的方法。在这种情况下,它将找到具有float基本数据类型的方法并调用它。
// Java展示拓展的方法重载
import java.io.*;
public class Conversion
{
// 重载方法
public void method(int i)
{
System.out.println("原始数据类型int形参 :" + i);
}
// 原始类型形参重载
public void method(float i)
{
System.out.println("原始数据类型float形参 :" + i);
}
}
class GFG
{
public static void main (String[] args)
{
Conversion c = new Conversion();
// 调用方法,此方法签名有拓展的参数类型
c.method(10);
c.method(new Long(100));
}
}
输出:
原始数据类型int形参 :10
原始数据类型float形参 :100.0
方法重载与拓展和装箱在一起
如果拓展和装箱同时发生会怎样?编译器可以执行什么方法调用?
原始类型的扩展已优先于装箱boxing和var-args。但是原始类型的扩展和装箱不能一起使用。
// Java展示方法重载,拓展,装箱一起使用
import java.io.*;
public class Conversion
{
// 重载方法使用引用形参
public void method(Integer a)
{
System.out.println("原始数据类型byte形参 :" + a);
}
}
class GFG
{
public static void main (String[] args)
{
Conversion c = new Conversion();
// 调用方法
byte val = 5;
c.method(val);
}
}
输出:
25: error: incompatible types: byte cannot be converted to Integer
c.method(val);
^
Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error
但是如果将其传递给Object类型的引用,则可以接受装箱后的拓展。为此,请参见以下示例。
// Java展示接受自动装箱后的拓展
import java.io.*;
public class Conversion
{
// 重载方法,使用引用形参
public void method(Object b)
{
// 对象b先被转换成Byte,之后被打印
Byte bt = (Byte) b;
System.out.println("数据类型为引用形参 :" + bt);
}
}
class GFG
{
public static void main (String[] args)
{
Conversion c = new Conversion();
byte val = 5;
// b先被拓展成Byte
// 然后Byte被传递给Object.
c.method(val);
}
}
输出:
数据类型为引用形参 :5
使用Varargs参数的方法重载
基本类型的扩展比var-args具有更高的优先级。
例:
// Java使用var-args和拓展一起使用
import java.io.*;
public class Conversion
{
// 重载方法原始类型(byte),使用var-args形参
public void method(byte... a)
{
System.out.println("原始类型byte为形参:" + a);
}
// 重载方法,原始类型int形参
public void method(long a, long b)
{
System.out.println("加宽long形参 :" + a);
}
}
class GFG
{
public static void main (String[] args)
{
Conversion c = new Conversion();
// 调用方法,使用拓展原始类型参数
byte val = 5;
c.method(val,val);
}
}
输出:
Widening type long formal argument :5