什么是重载
如果多个方法有相同的名字、不同的参数,变产生了重载,Java允许重载如何方法,而不只是构造方法。
什么是方法的签名
说到重载就不得不说方法的签名,方法名以及参数类型就叫做方法签名。返回类型不是方法签名的 一部分。也就是说,不能有两个名字相同、参数类型也相同却返回不同类型值的方法。
为什么要重载
方法的重载其实也是多态的表现。这里以GregorianCalendar类中的构造方法为例,在这个类里有多个构造方法,其中有有参的和无参的,有参构造方法里面又由参数类型和个数不同类区分不同的有参构造方法,这正是运用了重载。这样的好处就是,当我们实例化GregorianCalendar类时可以通过选择运用不同的构造方法,实例化出状态不一样的对象,而这个过程我们都是在使用构造方法。假如没有重载,我们只能通过一种构造方法实例化出对象,灵活性低。也就是说重载提高了灵活性。
怎么实现重载
要问怎么实现重载,那就要了解调用对象方法的执行过程。
调用方法的执行过程
此过程中会产生两种分支,动态绑定和静态绑定(这里主要讲到动态绑定)
- 编译器查看对象的的声明类型和方法名。假设调动x.f(param),且隐式参数x声明为C类的对象。需要注意的是:有可能存在多个名字为f,但参数类型不一样的方法。例如,可能存在方法f(int)和f(String)。编译器会一一列举所有C类中名为f的方法和超类中访问属性为public且名为f的方法(超类的私有方法不可访问)。
至此,编译器已获得所有可能被调用的候选方法。 - 接下来,编译器将查看调用方法时提供的参数类型。如果在所有名为f的方法中存在一个与提供的参数类型完全匹配,就选择这个方法。这个过程被称为重载解析。例如:,对于调用x.f(“Hello”)来说,变异器将会挑选f(String),而不是f(int)。
至此,编译器已获得需要调用的方法名字和参数类型。 - 如果是private方法、static方法、final方法或者构造器,那么编译器将可以准确的知道应该调用哪个方法,我们将这种调用方式称为静态绑定。与次对应的是,调用的方法依赖于隐式参数(对象)的实际类型,并且在运行时实现动态绑定。
- 当程序运行,并且采用动态绑定调用方法时,虚拟机一定调用与x所引用对象的实际类型最合适的那个类型的方法。假设x的实际类型时D,它是C类的子类。如果D类定义了方法f(String),就直接调用它;否则,将在D类的超类中寻找f(String),以此类推。
每次调用方法都要进行搜索,时间开销相当大。因此,虚拟机预先为每个类创建了一个方法表,其中列出所有方法的签名和实际调用的方法。当调用方法是,虚拟机仅查找这个表。
重载的特点
- 方法名相同;
- 参数列表数量或类型不同;
- 与返回类型无关;