22.5种方法调用指令-invokestatic,invokespecial,invokevirtual,invokeinterface,invokedynamic
1.虚方法与非虚方法
1.静态方法、私有方法、final方法、实例构造器、父类方法都是非虚方法,其他方法都是虚方法。
2. 5种调用指令
a)invokestatic
b)invokespecial
c)invokevirtual
d)invokeinterface
e)invokedynamic
invokestatic
和invokespecial
调用的方法都是非虚方法,其余的方法(final
修饰的方法除外,final方法调用使用的是invokevirtual
,但是final
方法不能重写,所以认为final
是非虚方法)都是虚方法。
例子:
package jvn; class Father { public Father() { System.out.println("father的构造器"); } public static void showStatic(String str) { System.out.println("father " + str); } public final void showFinal() { System.out.println("father show final"); } public void showCommon() { System.out.println("father 普通方法"); } } public class Son extends Father { public Son() { //invokespecial super(); } public Son(int age) { //invokespecial this(); } //不是重写的父类的静态方法,因为静态方法不能被重写! public static void showStatic(String str) { System.out.println("son " + str); } private void showPrivate(String str) { System.out.println("son private" + str); } public void show() { //invokestatic showStatic("atguigu.com"); //invokestatic super.showStatic("good!"); //invokespecial showPrivate("hello!"); //invokespecial super.showCommon(); //invokevirtual showFinal();//因为此方法声明有final,不能被子类重写,所以也认为此方法是非虚方法。 //虚方法如下: //invokevirtual showCommon(); info(); MethodInterface in = null; //invokeinterface in.methodA(); } public void info(){ } public void display(Father f){ f.showCommon(); } public static void main(String[] args) { Son so = new Son(); so.show(); } } interface MethodInterface{ void methodA(); }
使用Jclasslib
打开编译生成的class
文件。选择show
方法,查看字节码指令。
静态方法都是使用invokestatic
调用。
私有方法是使用invokespecial
调用。
父类的普通方法是通过invokespecial
调用。
父类的final方法是通过invokevirtual
调用。
接口方法使用invokeinterface
调用。
e)关于invokedynamic
指令
1.静态类型语言和动态类型语言的区别:对类型的检查是在编译期还是在运行期。
例如:
Java定义一个字符串变量:String info = "test";
//如果写成info = test就会直接报错,根本不用运行。
而JS定义一个变量:var name = “test”;
// 只有等到js运行的时候才能确定这是一个字符串
1.java
是静态类型语言。
2.java8
为了支持动态类型语言开始支持invokedynamic
。
Java8中的lambda表达式会生成invokedynamic
指令:
package jvn; @FunctionalInterface interface Func { public boolean func(String str); } public class Lambda { public void lambda(Func func) { return; } public static void main(String[] args) { Lambda lambda = new Lambda(); Func func = s -> { return true; }; lambda.lambda(func); lambda.lambda(s -> { return true; }); } }
使用Jclasslib
打开上述代码生成的class
文件: