在 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(),但这是在某处指定的还是只是一个实现细节?
ASM javadoc 指定了所有方法调用的顺序,是的,根据合同,这个顺序是有保证的,visitAnnotation 在 visitCode 之前被调用。如果您使用 ClassReader 等官方 ASM 发射器,顺序将始终遵循规范。
然而,类型系统中没有内置顺序保证。任何人都可以实现不同的顺序,并且一些消费者(例如 ClassWriter)容忍这种偏差,即使它并不总是明确保证。
(由 kriegaex 更新) 如果您想确定地知道,只需查看明确记录的 ASM manual, chapter 3.2.1:
我只想检测用 @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(),但这是在某处指定的还是只是一个实现细节?
ASM javadoc 指定了所有方法调用的顺序,是的,根据合同,这个顺序是有保证的,visitAnnotation 在 visitCode 之前被调用。如果您使用 ClassReader 等官方 ASM 发射器,顺序将始终遵循规范。
然而,类型系统中没有内置顺序保证。任何人都可以实现不同的顺序,并且一些消费者(例如 ClassWriter)容忍这种偏差,即使它并不总是明确保证。
(由 kriegaex 更新) 如果您想确定地知道,只需查看明确记录的 ASM manual, chapter 3.2.1: