Java 注解中 String 类型的 default 一些疑问

2022-07-13 11:08:03 +08:00
 L0L

昨天在写代码中,发现了一个有趣的现象

简单描述一下过程

  1. 初步定义了一个注解,其中一个 name() 方法返回一个 String 类型;
  2. 指定了其默认值为一个静态的对象 Test.name;
  3. 通过 Main 函数进行执行,发现这两个对象运行时,竟不是同一个对象;
  4. JetBrain 的反编译功能查看,发现 Test.name 被转换成了 ‘123’ 的常量值。

其实这里更好奇的是,Java String Constant Pool 为什么没有起作用;

目前怀疑点还是在内存分配的空间上:由于常量字符串池是在堆上分配,而注解是在非堆(这点不是很确认)?

下面是代码:

package com.example._17.demo.blog;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

public class Question {

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @interface Test {

        String name = "123";

        String name() default name;
    }

    @Test
    public final String demo = "123";

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        
        Field field = Question.class.getField("demo");
        Test annotation = field.getAnnotation(Test.class);
        System.out.println(annotation.name() == Test.name);
    }
}

1351 次点击
所在节点    程序员
5 条回复
siweipancc
2022-07-13 11:28:46 +08:00
L0L
2022-07-13 11:39:17 +08:00
@siweipancc Thranks ,我再去试一下
lancelee01
2022-07-13 11:49:40 +08:00
会不会是由于每个变量都可以设置注解 name 属性的值,所以这个地方每次都是新建的
L0L
2022-07-13 12:28:49 +08:00
@lancelee01 1 楼的大佬是正解
L0L
2022-07-13 21:58:50 +08:00
@L0L
debug 了一波,简单总结下:
1. 注解中的方法默认使用了的静态常量值;经过反射获取到的该默认值,与原本的静态常量值对象是不相同的(!=);
(注解的默认值通过 `AnnotationParser.parseMemberValue` 重新产生了一个新的对象)

2. 不同的属性(方法,类等)上的注解,通过反射获取到的注解实例,都是不同的对象(!=);
(注解对象是通过 JDK 动态代理生成的,所以每一个都是不同的呢)

3. 不同的注解实例,如果使用的都是默认值的话,每一个默认值的对象都是相同的(==);
(该对象存储在 AnnotationType 上[我理解为一层 java 缓存],通过 cas 保证线程安全)

4. 如果显示的指定具体注解的值(即使是静态常量值),最终获得的默认值对象都是不相同的(!=);
(每一个注解的默认值,都是通过 `AnnotationParser.parseMemberValue` 产生的,顾与 **1** 是一致的 )

JVM 层为什么没有使用到常量池,还在学习 ing (暂时看不懂 CPlusPlus o(╥﹏╥)o );

欢迎大家指正...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/865859

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX