网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 后端开发 > Java >

Java注解相关笔记

时间:2025-03-17 22:58

人气:

作者:admin

标签:

导读:注解 工作原理 package com.breeze.rewrite_mybatis; import java.lang.annotation.*; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) public @i...

注解

工作原理
package com.breeze.rewrite_mybatis;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface AliasFor {
    @AliasFor("attribute")
    String value() default "";

    @AliasFor("value")
    String attribute() default "";

}

package com.breeze.rewrite_mybatis;

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

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {

    @AliasFor("value")
    String tableName() default "";

    @AliasFor("tableName")
    String value();//value不能为空

}

package com.breeze.rewrite_mybatis;

@Table("sys_user")
public class User {
    ...
}

package com.breeze.rewrite_mybatis;
@Table("sys_user2")
public class User2 {
    ...
}


//在com.breeze.rewrite_mybatis.Main类下
public static void main(String[] args){
    User user1 = new User();
    Table table = user1.getClass().getAnnotation(Table.class);
    System.out.println(table.value());//sys_user
    System.out.println(Table.class);//interface com.breeze.rewrite_mybatis.Table
    System.out.println(table.getClass());//class com.sun.proxy.$Proxy1
    System.out.println(table.annotationType());//interface com.breeze.rewrite_mybatis.Table
    
    User2 user2 = new User2();
    Table table2 = user2.getClass().getAnnotation(Table.class);
    System.out.println(table2.value());//sys_user2
    System.out.println(table2.getClass());//class com.sun.proxy.$Proxy1,在本例中,是$Proxy1,但是在其他代码中,执行时,可能有很多动态代理对象,可能时$ProxyN(N是非0的自然数),这里只是表示其是一个代理对象
    System.out.println(table.getClass() == table2.getClass());//true
    System.out.println(table2.annotationType());//interface com.breeze.rewrite_mybatis.Table
    
    System.out.println(table.getClass().getMethod("value").getAnnotation(AliasFor.class) == null);//true
    
    Method valueMethod = Table.class.getMethod("value");
    AliasFor annotation = valueMethod.getAnnotation(AliasFor.class);
    if (annotation != null) {
        System.out.println(annotation.getClass());//class com.sun.proxy.$Proxy2,在本例中,是$Proxy2,但是在其他代码中,执行时,可能有很多动态代理对象,可能时$ProxyN(N是非0的自然数),这里只是表示其是一个代理对象
        System.out.println("AliasFor注解的关联属性:" + annotation.value());//AliasFor注解的关联属性:tableName
    }
}

在 Java 中,注解(Annotation,注解在Java中实际上是一种特殊的接口)是通过动态代理机制实现的。当通过反射,获取注解实例时,实际上获取的是一个由 JVM 动态生成的代理对象,而非注解接口本身的实例。

Java 注解(如 @Table本质上是一个接口,但运行时通过反射获取的注解实例,是一个代理对象(由sun.reflect.annotation.AnnotationInvocationHandler 生成)。

如果要判断 table 是否是 @Table 注解的实例,应使用 Annotation.annotationType() 方法获取注解的真实类型。

总结

一个注解,在JVM运行中,对应一个代理类(com.sun.proxy.$ProxyN,N是非0的自然数),获取到的注解实例,是这个代理类的对象。

这也是,Java语言中,万物皆对象的一个体现,因为注解的本质是接口,接口并不是类,而想创建注解的对象,自然需要创建,一个动态代理类,才能创建对象。因为类才能创建对象,接口是不能的。

这里给出一个说明,在Java的lamda表达式,和函数引用中,看上去,是创建了一个接口的对象,但其本质还是一个匿名内部类的对象。

//在com.breeze.rewrite_mybatis.Main类下
Function<String,String> function = s1 -> s1 + ":" + s1;
Function<String,String> function2 = String::toLowerCase;
System.out.println(function2.getClass());//class com.breeze.rewrite_mybatis.Main$$Lambda$2/1828972342
System.out.println(function.getClass());//class com.breeze.rewrite_mybatis.Main$$Lambda$1/1989780873
System.out.println(table.getClass().getMethod("value").getAnnotation(AliasFor.class) == null);//true

从上面,这个代码片段,可以看出,注解代理类对象中,并没有织入这个注解(接口)的方法上修饰的注解信息。所以,要获取注解的方法上的注解信息,必须获取到,注解接口的class对象的class对象(注解.class如Table.class,或者使用代理类对象的annotationType()方法获取),而非注解代理类的class对象。

    //在com.breeze.rewrite_mybatis.Main类下    
    Method valueMethod = Table.class.getMethod("value");
    AliasFor annotation = valueMethod.getAnnotation(AliasFor.class);
    if (annotation != null) {
        System.out.println(annotation.getClass());//class com.sun.proxy.$Proxy2,在本例中,是$Proxy2,但是在其他代码中,执行时,可能有很多动态代理对象,可能时$ProxyN(N是非0的自然数),这里只是表示其是一个代理对象
        System.out.println("AliasFor注解的关联属性:" + annotation.value());//AliasFor注解的关联属性:tableName
    }

通过类似,上述代码片段的方式,获取@Table中方法的注解信息和值。

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信