重载和重写的区别

二者的定义:

1、重载发生在同一个类中,若多个方法之间方法名相同、参数列表不同,则它们构成重载的关系。重载与方法的返回值以及访问修饰符无关,即重载的方法不能根据返回类型进行区分。
2、重写发生在父类子类中,若子类方法想要和父类方法构成重写关系,则它的方法名、参数列表必须与父类方法相同。另外,返回值要小于等于父类方法,抛出的异常要小于等于父类方法,访问修饰符则要大于等于父类方法。还有,若父类方法的访问修饰符为private,则子类不能对其重写。

编译和运行的角度来看

1、方法重载,是通过静态解析实现的,静态解析是指有些符号引用是在类加载阶段或是第一次使用时就会转换成直接引用。编译器就可以完全确定,既然是静态的行为,那么调用方法传的参数则会只认变量的静态类型,而非变量的实际类型(其他静态解析有静态方法,父类方法,构造方法,私有方法)
2、方法重写,是通过动态分派实现的,动态分派是指一些符号引用则是在每次运行期转换为直接引用。在字节码层面是通过invokevirtual字节码指令实现的,invokevirtual多态查找的过程是①:首先在操作数栈的栈顶去寻找到栈顶的元素所指向对象的实际类型。②:在该实际类型的对象当中,如果寻找到了与常量池中描述符和名称都相同的方法,并且具备相应的访问权限,就会直接返回目标方法的直接引用(就是Apple.test())③:如果在实际类型的对象中没有找到该方法,那么就去其父类,继续执行该查找流程,直到找到,或者抛出异常

你可能感兴趣的:(重载和重写的区别)