java注解的基本原理和编程实现

java 1.5开始引入了注解和反射,正确的来说注解是反射的一部分,没有反射,注解无法正常使用,但离开注解,反射依旧可以使用,因此来说,

反射的定义应该包含注解才合理一些。当然,这只是个人想法,至于java官方为什么这么泾渭分明不得而知,最重要的是如何使用注解。

 

注解的功能分为2部分:

  1. 作为特定的标记

  2. 额外信息的载体

 

>>>>定义一个UserAnnotation注解类

@Target(value = { ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface UserAnnotation {
	public int id() default 0;
	public String name() default "";
	public int age() default 18;
	public String gender() default "M";
}

 

其中@target个@Retention本身就是注解

【@target】这个注解来指定给哪一类java成员注解,指定注解目标该是什么样的东西

注解@Target的源码

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE) //这不是在作弊,这确实是自己注解自己,所以说注解也可以被字节给注解
public @interface Target {
    ElementType[] value(); //值可以使数组 value={...}
}

public enum ElementType {
    TYPE,  //给类(型)注解
    FIELD, //给字段注解,不要忘了,字段可以是对象
    METHOD, //给方法注解
    PARAMETER, //给参数注解
    CONSTRUCTOR, //给构造方法注解
    LOCAL_VARIABLE, //给局部变量注解
    ANNOTATION_TYPE,//给注解注解(这貌似把自己不当类来看)
    PACKAGE, //给包注解
    TYPE_PARAMETER, //不知道,等知道了我再写在这里
    TYPE_USE //这个也不知道
}

 

【@Retention】表示注解运行的状态,换句话说,注解改在什么样的状态下才能运行

注解@Retention的源码

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

public enum RetentionPolicy {
    SOURCE, //源码状态运行,
    CLASS, //编译类文件时运行
    RUNTIME //运行时运行
}

 

一般来说,源码状态运行和编译状态运行的注解往往和编译器相关,比如报错,警告,类编译参数等,这2类状态一般和编辑器插件关系密切,这里不再讨论

在日常开发中RUNTIME用的最多,这是开发人员可以控制的一个状态。

 

【@Documented】额,不多解释,具体来说是生成说明文档时把类的解释添加进去。

 

关于注解的方法说明,注解只有方法,没有字段,因为注解也是一个interface,只不过前面加了一个@符号,还有一点是这些方法无法实现,写法和C++的纯虚函数相似

请看id()方法的解释

 public int id() default 0; 
/*首先,方法必须是public的,去掉public,默认也是public,接口interface不也是这样么
 *
 *其次,default默认值不是必须的,方法必须有返回值,返回值可以是java中复杂对象,也可以是基本类型,枚举都行
 *如 ElementType[] value();
 */

 

注解定义好了,怎么使用呢,如下

public class TestMain
{
  @UserAnnotation(age=20,gender="F",id=2014,name="zhangsan")//注解的使用
  private Object obj;
  
  public static void main(String[] args) throws Exception
  {
     Filed objField = TestMain.class.getField("obj");
     UserAnnotation ua = objField.getAnnotation(UserAnnotation.class);//得到注解,起到了标记的作用
     
    System.out.println(ua.age()+","+ua.gender()+","+ua.id()+","+ua.name());
    //***进一步操作的话,假设Object要指向一个User类,那么可以讲注解的值给他
    TestMain tm = new TestMain();
    objFiled.set(tm,new User(ua.age(),ua.gender(),ua.id(),ua.name())); //不错吧,将自己的信息送给obj,起到了附加信息的作用
    
    //-----------请自由遐想吧~~,下面来说说注解怎么能获得注解自己的注解-------------
   Target t = ua.annotationType().getAnnotation(Target.class)
   ElementType[] values = t.value();
   //~~~~~~~~~~~~~~完了,再一次自由遐想吧~~~~~~~~~~~~~~
   
   Sysout.out.println("注意:是遐想,不是瞎想!!");
  }
}

欢迎工作一到五年的Java工程师朋友们加入Java技术交流群:659270626
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

 

### Java注解实现原理 Java注解是一种元数据形式,提供有关程序的数据。这些信息可以被编译器读取并用于验证代码或生成额外的信息。自Java 5起引入了注解功能,并放置于`java.lang.annotation`包中[^2]。 #### 系统自带注解及其处理方式 存在三类主要的注解类别: - **内置系统注解**:像`@Override`这样的预定义注解由JVM负责解释执行,主要用于增强编程模型的安全性一致性检查。 - **用户自定义注解**:开发者可以根据需求创建自己的注解类型来标记源码的不同部分(方法、字段等),并通过反射API在运行时获取响应这些标签所携带的信息。为了使自定义注解生效,通常还需要编写相应的处理器逻辑去解析它们的行为意图。 - **元注解**:用来修饰其他注解类型的特殊注解,总共有四个标准元注解[@Documented](https://docs.oracle.com/javase/8/docs/api/java/lang/annotation/Documented.html),其作用是指定当使用该注解的地方是否会被包含到通过工具如javadoc生成的文档里;另外三个分别为控制保留策略(`@Retention`)、目标适用范围(`@Target`)以及组合重复使用的容器(`@Repeatable`)。 对于如何具体实现一个简单的自定义注解,下面给出了一段示范性的代码片段展示基本结构: ```java import java.lang.annotation.*; // 定义一个新的注解 @MyCustomAnnotation 并设置它的属性 @Retention(RetentionPolicy.RUNTIME) // 表明此注解会在运行期可见 @Target(ElementType.METHOD) // 只能应用于方法上 public @interface MyCustomAnnotation { String value() default "default"; } ``` 接着可以在任何合适的位置利用上述新建立好的注解进行装饰操作: ```java public class ExampleClass { @MyCustomAnnotation(value="exampleValue") public void exampleMethod(){ System.out.println("This method is annotated."); } // 使用反射技术访问带有特定注解的方法实例 Method[] methods = this.getClass().getDeclaredMethods(); for (Method m : methods){ if(m.isAnnotationPresent(MyCustomAnnotation.class)){ MyCustomAnnotation annotation = m.getAnnotation(MyCustomAnnotation.class); System.out.println(annotation.value()); } } } ``` 这段例子展示了怎样声明一个可选参数化的注解,并且演示了通过反射机制检索已应用此类注解的对象成员的过程。值得注意的是,只有设置了适当生命周期特性的注解才能确保能够在应用程序启动之后仍然保持有效状态以便后续查询调用[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值