在类加载的解析阶段,会将其中的一部分符号引用转化为直接引用,这些转化的前提条件是方法在运行之前就有一个可确定的调用版本,并且这个方法的调用版本在运行时期是不可变的。这类方法的调用叫做解析。 符合上述规则的方法有: 静态方法 私有方法 实例构造器方法 父类方法 用final修饰的方法 这些方法都被字节码指令invokespecial 和invokestatic 指令调用。这些方法也叫做非虚方法。 而其他的方法称为虚方法,此类方法须在运行时确定,并由invokeirtual字节码调用。 重载和重写的区别 重载相对的是方法的参数 重写是方法的调用者, 如Object.method(Object...args) 重载要确定的是args参数是什么,即参数的静态类型,而不是动态类型; 重写要确定的是Object是什么。 当一个对象调用方法时: 判断调用者是否具有动态性(也即调用的方法是否是覆盖了父类的方法),如果有则根据方法定义中参数的静态类型来执行; public class HelloWorld { /** * @param args */ static class _360 { public static void print(){ System.out.print("360"); } } static class _361 extends _360{ public static void print(){ System.out.print("361"); } }; static class QQ {} public static class Father{ public void hardChoice(_360 args){ System.out.print("father choose 360\n"); args.print(); } public void hardChoice(QQ args){ System.out.print("father choose QQ"); } } public static class Son extends Father{ public void hardChoice(_360 args){ System.out.print("son choose 361"); args.print(); } public void hardChoice(QQ args){ System.out.print("son choose QQ"); } } public static void main(String[] args) { // TODO Auto-generated method stub Father father=new Father(); _360 a360=new _360(); _361 b361=new _361(); Father son=new Son(); son.hardChoice(b361); System.out.print("\t"); son.hardChoice(new QQ()); } } 输出结果:son choose 361 360 son choose QQ 如果没有,则根据调用者的静态类型来调用方法。方法的参数则以方法定义中的参数的静态类型来执行; public class HelloWorld { /** * @param args */ static class _360 { public static void print(){ System.out.print("360"); } } static class _361 extends _360{ public static void print(){ System.out.print("361"); } }; static class QQ {} public static class Father{ public void hardChoice(_360 args){ System.out.print("father choose 360\n"); args.print(); } public void hardChoice(QQ args){ System.out.print("father choose QQ"); } } public static class Son extends Father{ public void hardChoice(_361 args){ System.out.print("son choose 361"); args.print(); } public void hardChoice(QQ args){ System.out.print("son choose QQ"); } } public static void main(String[] args) { // TODO Auto-generated method stub Father father=new Father(); _360 a360=new _360(); _361 b361=new _361(); Son son=new Son(); son.hardChoice(b361); System.out.print("\t"); son.hardChoice(new QQ()); } } 输出结果:son choose 361 361 son choose QQ 所以说 java 是一种静态单分派、动态多分派的语言。 |
|