在 ASM 库中,visitAnnotation() 是否总是在 visitCode() 之前调用?

Is visitAnnotation() always called before visitCode() in the ASM library?

我只想检测用 @Test 注释的方法,所以在调用 visitCode() 之前,我想知道它是否用 @Test 注释。从我运行的测试来看,我可以说visitAnnotation()总是先被调用,但我不知道是否总是这样,或者有例外。

更新:来自 ASM 的代码:

这是调用 visitAnnotation() 的地方:

if (runtimeVisibleAnnotationsOffset != 0) {
    attributeLength = this.readUnsignedShort(runtimeVisibleAnnotationsOffset);

    for (currentAnnotationOffset = runtimeVisibleAnnotationsOffset + 2; attributeLength-- > 0;
     currentAnnotationOffset = this.readElementValues(methodVisitor.visitAnnotation(annotationDescriptor, true), currentAnnotationOffset, true, charBuffer)) {
        annotationDescriptor = this.readUTF8(currentAnnotationOffset, charBuffer);
        currentAnnotationOffset += 2;
    }
}
...
...

然后调用 visitCode():

 if (codeOffset != 0) {
     methodVisitor.visitCode();
     this.readCode(methodVisitor, context, codeOffset);
  }

因此很明显,首先调用了 visitAnnotation(),但这是在某处指定的还是只是一个实现细节?

A​​SM javadoc 指定了所有方法调用的顺序,是的,根据合同,这个顺序是有保证的,visitAnnotation 在 vi​​sitCode 之前被调用。如果您使用 ClassReader 等官方 ASM 发射器,顺序将始终遵循规范。

然而,类型系统中没有内置顺序保证。任何人都可以实现不同的顺序,并且一些消费者(例如 ClassWriter)容忍这种偏差,即使它并不总是明确保证。


(由 kriegaex 更新) 如果您想确定地知道,只需查看明确记录的 ASM manual, chapter 3.2.1