非虚方法:只能被invokestatic和invokespecial指令调用的方法,称为非虚方法,常见的非虚方法有:静态方法、私有方法、实例构造器、父类方法四种。
虚方法:除非虚方法以外的其它方法。
注意:被final修饰的方法,虽然是invokevirtual指令调用,但依然为非虚方法,代码如下:
Java代码:
public class User {
private Long userId;
public User() {
}
public User(Long userId) {
this.userId = userId;
}
}
public class SuperClass {
public void superMethod(){
}
}
public class InvokeMethods extends SuperClass {
public static void main(String[] args) {
InvokeMethods finalMethodTest = new InvokeMethods();
//调用被final修饰的方法
finalMethodTest.finalMethod();
//调用被static修饰的方法
InvokeMethods.staticMethod();
//调用被private修饰的方法
finalMethodTest.privateMethod();
//调用父类方法
finalMethodTest.superMethod();
//调用构造器
User user = new User();
}
public final void finalMethod(){
}
public static void staticMethod(){
}
private void privateMethod(){
}
}
字节码:
// class version 52.0 (52)
// access flags 0x21
public class demo/InvokeMethods extends demo/SuperClass {
// compiled from: InvokeMethods.java
// access flags 0x1
public <init>()V
L0
LINENUMBER 6 L0
ALOAD 0
INVOKESPECIAL demo/SuperClass.<init> ()V
RETURN
L1
LOCALVARIABLE this Ldemo/InvokeMethods; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x9
public static main([Ljava/lang/String;)V
L0
LINENUMBER 9 L0
NEW demo/InvokeMethods
DUP
INVOKESPECIAL demo/InvokeMethods.<init> ()V
ASTORE 1
L1
LINENUMBER 11 L1
ALOAD 1
INVOKEVIRTUAL demo/InvokeMethods.finalMethod ()V //final方法的调用
L2
LINENUMBER 13 L2
INVOKESTATIC demo/InvokeMethods.staticMethod ()V //静态方法调用
L3
LINENUMBER 15 L3
ALOAD 1
INVOKESPECIAL demo/InvokeMethods.privateMethod ()V //私有方法调用
L4
LINENUMBER 17 L4
ALOAD 1
INVOKEVIRTUAL demo/InvokeMethods.superMethod ()V //调用父类方法
L5
LINENUMBER 19 L5
NEW demo/User
DUP
INVOKESPECIAL demo/User.<init> ()V //调用类构造器
ASTORE 2
L6
LINENUMBER 20 L6
RETURN
L7
LOCALVARIABLE args [Ljava/lang/String; L0 L7 0
LOCALVARIABLE finalMethodTest Ldemo/InvokeMethods; L1 L7 1
LOCALVARIABLE user Ldemo/User; L6 L7 2
MAXSTACK = 2
MAXLOCALS = 3
// access flags 0x11
public final finalMethod()V
L0
LINENUMBER 24 L0
RETURN
L1
LOCALVARIABLE this Ldemo/InvokeMethods; L0 L1 0
MAXSTACK = 0
MAXLOCALS = 1
// access flags 0x9
public static staticMethod()V
L0
LINENUMBER 28 L0
RETURN
MAXSTACK = 0
MAXLOCALS = 0
// access flags 0x2
private privateMethod()V
L0
LINENUMBER 32 L0
RETURN
L1
LOCALVARIABLE this Ldemo/InvokeMethods; L0 L1 0
MAXSTACK = 0
MAXLOCALS = 1
}