1.静态方法、私有方法、final方法、实例构造器、父类方法都是非虚方法,其他方法都是虚方法。
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
文件:
更多JVM文章请访问我的JVM专栏:
https://blog.csdn.net/u011069294/category_10113093.html