为什么使用invokevirtual操作码

时间:2018-04-03 15:13:03

标签: java

继承的类不能覆盖java中的最终方法。

但是为什么使用invokevirtual而不是invokespecial调用最终方法。

1 个答案:

答案 0 :(得分:3)

final修饰符的语义仅由字节码编译器强制执行。

The link to JavaSE7 specification Some other samples about final keyword.

  

invokespecial和invokevirtual指令之间的区别在于invokevirtual根据对象的类调用方法。 invokespecial指令用于调用实例初始化方法以及当前类的超类的私有方法和方法。

当我们调用final方法时,相应的字节码指令为INVOKEVIRTUAL,与其他非最终方法相同。

以下是使用final关键字调用方法的示例。

CounterPoint.java

public class CounterPoint extends Point {

    private static final AtomicInteger counter = new AtomicInteger();

    public CounterPoint(int x, int y) {
        super(x, y);
        counter.incrementAndGet();
    }

    public static String numberCreated() {
        return counter.toString();
    }

}

CounterPoint的ByteCode

// class version 52.0 (52)
// access flags 0x21
public class com/xetrasu/CounterPoint extends java/awt/Point  {

  // compiled from: CounterPoint.java

  // access flags 0x1A
  private final static Ljava/util/concurrent/atomic/AtomicInteger; counter

  // access flags 0x1
  public <init>(II)V
   L0
    LINENUMBER 11 L0
    ALOAD 0
    ILOAD 1
    ILOAD 2
    INVOKESPECIAL java/awt/Point.<init> (II)V
   L1
    LINENUMBER 12 L1
    GETSTATIC com/xetrasu/CounterPoint.counter : Ljava/util/concurrent/atomic/AtomicInteger;
    INVOKEVIRTUAL java/util/concurrent/atomic/AtomicInteger.incrementAndGet ()I
    POP
   L2
    LINENUMBER 13 L2
    RETURN
   L3
    LOCALVARIABLE this Lcom/xetrasu/CounterPoint; L0 L3 0
    LOCALVARIABLE x I L0 L3 1
    LOCALVARIABLE y I L0 L3 2
    MAXSTACK = 3
    MAXLOCALS = 3

  // access flags 0x9
  public static numberCreated()Ljava/lang/String;
   L0
    LINENUMBER 16 L0
    GETSTATIC com/xetrasu/CounterPoint.counter : Ljava/util/concurrent/atomic/AtomicInteger;
    INVOKEVIRTUAL java/util/concurrent/atomic/AtomicInteger.toString ()Ljava/lang/String;
    ARETURN
    MAXSTACK = 1
    MAXLOCALS = 0

  // access flags 0x8
  static <clinit>()V
   L0
    LINENUMBER 8 L0
    NEW java/util/concurrent/atomic/AtomicInteger
    DUP
    INVOKESPECIAL java/util/concurrent/atomic/AtomicInteger.<init> ()V
    PUTSTATIC com/xetrasu/CounterPoint.counter : Ljava/util/concurrent/atomic/AtomicInteger;
    RETURN
    MAXSTACK = 2
    MAXLOCALS = 0
}

AtomicInteger.java

public class AtomicInteger extends Number implements java.io.Serializable {
    public String toString() {
        return Integer.toString(get());
    }
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }
}