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
文件: