diff --git a/spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileAnnotationMetadata.java b/spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileAnnotationMetadata.java index 929535f6fbe..99c5bab22b0 100644 --- a/spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileAnnotationMetadata.java +++ b/spring-core/src/main/java24/org/springframework/core/type/classreading/ClassFileAnnotationMetadata.java @@ -195,7 +195,7 @@ final class ClassFileAnnotationMetadata implements AnnotationMetadata { builder.accessFlags(flags); } case NestHostAttribute _ -> { - builder.enclosingClass(classModel.thisClass()); + builder.enclosingClassFromNestHost(classModel.thisClass()); } case InnerClassesAttribute innerClasses -> { builder.nestMembers(currentClassName, innerClasses); @@ -256,11 +256,16 @@ final class ClassFileAnnotationMetadata implements AnnotationMetadata { this.accessFlags = accessFlags; } - void enclosingClass(ClassEntry thisClass) { + void enclosingClassFromNestHost(ClassEntry thisClass) { + if (this.enclosingClassName != null) { + return; + } String thisClassName = thisClass.name().stringValue(); int currentClassIndex = thisClassName.lastIndexOf('$'); - this.enclosingClassName = ClassUtils.convertResourcePathToClassName( - thisClassName.substring(0, currentClassIndex)); + if (currentClassIndex > 0) { + this.enclosingClassName = ClassUtils.convertResourcePathToClassName( + thisClassName.substring(0, currentClassIndex)); + } } void superClass(Superclass superClass) { @@ -280,6 +285,8 @@ final class ClassFileAnnotationMetadata implements AnnotationMetadata { if (currentClassName.equals(innerClassName)) { // the current class is an inner class this.innerAccessFlags = classInfo.flags(); + classInfo.outerClass().ifPresent(outerClass -> + this.enclosingClassName = ClassUtils.convertResourcePathToClassName(outerClass.name().stringValue())); } classInfo.outerClass().ifPresent(outerClass -> { if (outerClass.name().stringValue().equals(currentClassName)) { diff --git a/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java b/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java index 3b4b1fcf007..f5d163797e9 100644 --- a/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java +++ b/spring-core/src/test/java/org/springframework/core/type/AbstractAnnotationMetadataTests.java @@ -148,6 +148,14 @@ public abstract class AbstractAnnotationMetadataTests { assertThat(get(AbstractAnnotationMetadataTests.class).getEnclosingClassName()).isNull(); } + @Test + void getEnclosingClassNameWhenNestedMemberClassReturnsImmediateEnclosingClass() { + assertThat(get(TestNestedMemberClass.TestMemberClassInnerClassA.class).getEnclosingClassName()) + .isEqualTo(TestNestedMemberClass.class.getName()); + assertThat(get(TestNestedMemberClass.TestMemberClassInnerClassA.TestMemberClassInnerClassAA.class).getEnclosingClassName()) + .isEqualTo(TestNestedMemberClass.TestMemberClassInnerClassA.class.getName()); + } + @Test void getSuperClassNameWhenHasSuperClassReturnsName() { assertThat(get(TestSubclass.class).getSuperClassName()).isEqualTo(TestClass.class.getName());