Java的重载的类型匹配

xiaoxiao2025-12-08  2

[b][color=red][size=medium]本文版权归作者所有,仅供用来网上学习来用,读者可以收藏,请不要下载到本机和重新发布到其它网站[/size][/color][/b] 在Java 中,同一个类中的2个或2个以上的方法可以有同一个名字,只要它们的参数声明不同即可。在这种情况下,该方法就被称为重载(overloaded ),这个过程称为方法重载(method overloading )。 这篇文章不是为了讲什么是重载,怎么重载,而是为了举例重载时的一种特殊情况。 上面也说了,重载是方法名同,而参数的声明不同。参数的声明不同不包括参数名不同,而是参数的类型不同。下面给出几种正确的方法重载的例子: public class OverloadEx { public static void test() { System.out.println("test()"); } public static void test(String arg) { System.out.println("test(String)"); } public static void test(String arg0, int arg1) { System.out.println("test(String, int)"); } public static void test(String arg0, Integer arg1) { System.out.println("test(String, Integer)"); } public static void test(int arg0, String arg1) { System.out.println("test(int, String)"); } public static void test(Integer arg0, String arg1) { System.out.println("test(Integer, String)"); }} 从上面的代码可以看出,这几个test方法名称不用说都是相同的,但参数列表不同。前三个test方法的重载是因为参数的个数不同。第三个和第四个test方法,第五个和第六个test方法是因为参数的类型不同。而第三个和第五个,第四个和第六个是因为参数的位置不同。因些参数声明不同包括参数的个数,参数的类型,参数的顺序,但不包括参数名不同。像下面这种形式是错误的,不仅不是重载,连编译也不会通过,因为这两个方法其实是同一个方法。 public static void test(String arg00, int arg01);public static void test(String arg10, int arg11); 我们来看第一个方法执行的结果,首先我们写一个main方法来做个测试,分别调用这几个方法。有一点说明,测试是基于JRE5.0以后的版本。这时,由于JRE支持int和Integer类型的自动转换,这样的重载很容易出BUG。 在写这个测试方法之前,我们先看一个关于基本数据类型和其封装类自动转换的例子,这一内容会在后面的文章中专门写。 public class AutoTypeTrans { public static void main(String[] args) { int i0 = 0; Integer i1 = 1; Integer i2 = new Integer(2); test(i0); test(i1); test(i2); } public static void test(Integer integer) { System.out.println(integer); }} 结果是: 0 1 2 从结果上看,当程序执行到第8行时,发现i0为int类型,而方法的参数需要的是Integer类型,JVM会把i0自动转换成Integer,然后执行test(Integer)方法。 看完上面的自动类型转换的小例子,再看第一个例子的测试方法 public static void main(String[] args) { int i = 10; Integer integer = i; String s = "test"; test(); test(s); test(s, i); test(s, integer); test(i, s); test(integer, s);} 程序执行的结果是: test() test(String) test(String, int) test(String, Integer) test(int, String) test(Integer, String) 很明显,JRE会按照最精确匹配上的方法执行。JVM在执行过程中,会首先去匹配最精确匹配的方法,如果不能找,则寻找可进行自动类型转换后能匹配上的方法。 这个过程如果程序员不注意的话,很容易出现错误,尤其是有继承关系的时候,重载父类的方法容易出错,到时只好DEBUG来查了。 再看一下之方面的例子: public class InheritOverload { public static void main(String[] args) { int i = 0; Integer integer = new Integer(1); String s = "2"; Object obj1 = integer; Object obj2 = 4; Sub sub = new Sub(); sub.test(i); sub.test(integer); sub.test(s); sub.test(obj1); sub.test(obj2); }}class Base { public void test(int arg) { System.out.println("test(int)"); } public void test(Object arg) { System.out.println("test(Object)"); }}class Sub extends Base { public void test(Integer arg) { System.out.println("test(Integer)"); } public void test(String arg) { System.out.println("test(String)"); }} 结果是: test(int) test(Integer) test(String) test(Object) test(Object) 程序的第13行和第14行值得注意,obj1和obj2显然是Integer类型的,但是引用类型却是Object类型,JVM不会因为对象的真实类型是Integer类型,而去选择执行test(Integer),而是根据其引用类型Object选择了test(Object)。因为引用类型的自动转换只能从子类向其父类或父接口转换。 像这样继承结构比较复杂的系统中,注意重载时的参数的类型自动转换,不然很容易会出现意想不到的结果。
转载请注明原文地址: https://www.6miu.com/read-5040563.html

最新回复(0)