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
文件:
更多JVM文章請訪問我的JVM專欄:
https://blog.csdn.net/u011069294/category_10113093.html