方法重载中有趣的问题

看到一个比較有意思的问题

public class InvokeTest {

    public static void main(String[] args) {
        invoke(null);
    }

// method_1
    public static void invoke(Object obj) {
        System.out.println("Object obj");
    }

// method_2
    public static void invoke(int[] arr) {
        System.out.println("int[] arr");
    }

// method_3
    public static void invoke(int num) {
        System.out.println("int num");
    }
}

其运行结果是什么呢?

我的第一反应是 不能通过编译吧,我之前在工作中就遇到过类似的问题,是使用invoke((Object)null) 或invoke((int[])null)来确定详细调用哪个方法的.

然而实际情况是不但可以通过编译,并且调用的还是method_2

从运行结果来看JVM应该是会从子类開始匹配的,先找到method_2,所以就直接调用了,为此我进行了例如以下的证明

1.在測试类中再添加一个方法

// method_4
    public static void invoke(String str) {
        System.out.println("str");
    }

结果不能通过编译.

2.新增測试类:

public class Test {

	public static void main(String[] args) {
		invoke(null);
	}
	public static void invoke(Object obj) {
	    System.out.println("Object obj");
	}
	public static void invoke(Object1 arr) {
	    System.out.println("Object1");
	}
	public static void invoke(Object2 arr) {
	    System.out.println("Object2");
	}
	public static void invoke(Ojbect3 str) {
	    System.out.println("Ojbect3");
	}
}

class Object1 extends Object{}
class Object2 extends Object1{};
class Ojbect3 extends Object2{};

可以正确运行方法,调用的是Object3的方法.

结论:当使用null作为參数调用方法时,JVM会从底向上匹配的方式匹配方法,找到就运行.当不能正确匹配时,会报编译错误,须要强转null为指定的类型才干正确调用.

时间: 2024-10-09 13:10:55

方法重载中有趣的问题的相关文章

Java学习之方法重载和方法重写(覆盖)比较

方法重载和方法覆盖 请带着下面两点来看文章: 覆盖即重写,覆盖不等于重载,即重写不等于重载. 覆盖(重写)蕴含继承性,而重载只能在本类中使用,不含继承. 方法名和参数列表的比较 方法覆盖中的方法名和参数 首先创建基类Shape: public class Shape {   public void draw() { System.out.println("Shape.draw()"); } } 子类Circle: public class Circle extends Shape {

方法重载,为什么不能根据返回类型来区分?

详见:四 一.方法重载简述 任何程序设计语言都具备一项重要特性就是对名字的运用.当创建一个对象时,也就给此对象分配到的存储空间取一个名字. 所谓方法,则是给某个动作取的名字.通过这个名字,你可以引用所有的对象和方法.名字起的好可以使系统更易于理解和修改. 在日常生活中,相同的词可以表达多种不同的含义——它们被“重载”了.特别是含义之间的差别很小时,这种方式十分有用.比起“以洗衬衫的方式洗衬衫”.“以洗狗的方式洗狗”.“以洗车的方式洗车”,“洗洗衬衫”.“洗洗狗”.“洗洗车”显得更加简洁和方便.

蓝鸥Unity开发基础二——课时11 方法重载

一.方法重载 方法重载--多个不同的方法采用同样的名字 方法名相同,参数列表不同 1.未使用方法重载时候--两个整数和,两个小数和 using System; namespace Lesson11{    public  class Person{    public  int   Sum(int a,int b){        return a+b; }    public  float SumFloat(float a, float b){        return a+b;    }

JAVA SE中方法重载和方法重写及数据库中子程序的重载

首先方法重写和方法重载是建立在Java的面向对象的继承和多态的特性基础上而出现的.至于面向对象的继承和多态的特性我就不在这里多说了.继承是指在一个父类的基础再创建一个子类,这样子类就拥有了父类的非私有的特性,同时子类还可以扩展自己的特性,这样就引出了方法重写和方法重载! 一.方法重写(Override)         在Java中如何来定义重写:Java程序中类的继承特性可以产生一个子类,子类继承父类就拥有了父类的非私有的属性(方法和变量),在子类中可以增加自己的属性(方法和变量),同时也可以

java中的方法——重载

重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义. 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性. (3) 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同.无法以返回

javascript中的方法重载

在很多面向对象的高级语言中,都有方法的重载.而javascript没有方法重载这个概念.但是我们可以通过arguments这个参数来伪装成函数的重载 在模拟之前我们先看一下代码: //表面上没有声明形式参数的函数 function fun() { alert("示例代码"); } fun("小明", 100, true);//自己写了三个实际参数 通过结果我们看到,即使我们声明函数的时候没有定义形式参数,在调用方法的时候,我们也是可以写实际参数的.(实际上形式参数是

java面向对象中的方法重载与方法重写的区别

一.方法重载(overload) a:一个类中允许声明多个方法 b:一个类中允许有多个方法名称一样,但是参数不同的多个方法.通过参数不同来区别不同的方法. 参数不同表现为: 1:参数个数不同 2:参数类型不同 3:参数类型的顺序不同也是参数类型不同 4:在参数类型一样的情况下,名称不一样不代表参数不一样 重载方法的调用: 1:根据调用的时候实际参数来判断到底调用的是哪一方法 2:根据参数的要求,严格匹配传入的对应类型 3:如果严格匹配不到的话,默认遵循就近匹配 4:根据数据默认转换的顺序就近匹配

java中的方法重载与重写以及方法修饰符

1. 方法重载Overloading , 是在一个类中,有多个方法,这些方法的名字相同,但是具有不同的参数列表,和返回值 重载的时候,方法名要一样,但是参数类型和参数个数不一样,返回值类型可以相同,也可以不同, 不能以返回值类型判断方法是否重载. 2. 方法重写Overriding , 是存在于父类与子类之间 (1)若子类中的方法与父类中的某一方法具有相同的方法名.返回类型和参数表,则新方法覆盖父类中的方法,如需调 用父类方法用super关键字 (2)子类的重写方法的权限修饰符不能小于父类的,要

Java中的(构造方法、方法重载、final修饰符使用及继承和抽象)

构造方法: 构造方法的名称和类名相同,没有返回类型,参数列表(类型.个数)不同 方法重载:成员方法和构造方法都可以进行重载 方法名相同但是参数列表(类型,个数)不同,成为方法的重载. 继承:直支持单继承,一个类只能有一个父类 继承要用extends关键字修饰 public class Dog extends Pet{ //方法体 } 子类调用父类公用的成员变量和方法需使用关键字super 如super.方法名 super(成员变量,成员变量....) 方法重写: 方法重写的需求: 1.重写方法和