自定义注解(上)自定义注解的定义和检查

本文详细介绍了Java中的注解,包括注解的定义、自定义注解的创建过程,以及如何在运行时检查注解是否已加载。通过示例展示了注解在字段上的应用,并解释了@Target和@Retention的作用。同时,提供了检查注解实例化的代码示例,展示了如何在实际编程中使用注解。
摘要由CSDN通过智能技术生成

什么是注解?

注解是接口的一种变型,定义一组属性,让类、方法或属性用标记的方式调用这些属性。不仅是带有一些属性和值,某些注解带有一些特殊的功能。

如单元测试@Test,可以让方法不依赖主函数单独运行,右键方法体点击运行即可测试,免去了多次频繁创建删除类的操作。如图:

(结果如图,输出“ss”)


如何写自定义注解?

注解本质上是接口,所以定义注解的方式和定义接口很像。

选择新建文件,由于都是java文件,所以选择Java Class。但是注解并不是类。

在命名时选择注解Annotation

 

(其实选什么都不重要,创建出来后都是*.java的文件。即使在创建时选择不同的类型也不能起相同的名字)

(如再创建一个名为MyField的类,结果如下)

该注解的代码如下:

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

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyField {
    String description();
    int length() default 20;
}

//每个类只能定义一个注解

public @interface MyField是注解的定义方法,在接口前面加个@即可。

因为注解本质上是接口,所以只能定义属性不能定义方法,而且属性的定义也有一些不一样。定义的属性都要有个括号,且赋值时不能直接用等号,而是要用default。

说明:

其中的@Target声明了MyField的作用范围是属性(域)

@Retention声明了注解MyField在运行期间一直有效

这两个常见注解的其他用法:

 

Target:描述了注解修饰的对象范围,取值在java.lang.annotation.ElementType定义,常用的包括:

  • METHOD:用于描述方法
  • PACKAGE:用于描述包
  • PARAMETER:用于描述方法变量
  • TYPE:用于描述类、接口或enum类型
  • ANNOTATION_TYPE        :可用于注解类型上(被@interface修饰的类型)
  • CONSTRUCTOR:可用于构造方法上
  • FIELD:作用在域上
  • LOCAL_VARIABLE:可用于局部变量上

Retention: 表示注解保留时间长短。取值在java.lang.annotation.RetentionPolicy中,取值为:

  • SOURCE:在源文件中有效,编译过程中会被忽略
  • CLASS:随源文件一起编译在class文件中,运行时忽略
  • RUNTIME:在运行时有效

 

作者:快给我饭吃

链接:https://www.jianshu.com/p/a7bedc771204

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

 

补充:https://blog.csdn.net/u012992462/article/details/80675932


如何检查注解是否已经加载?

定义一个类

import org.junit.Test;
import java.lang.reflect.Field;

public class User{
    //使用我们的自定义注解
    @MyField(description = "用户名", length = 12)
    String s = "s";
    int i = 1;

    public static void main(String[] args) {
        //尝试使用@Test来测试所以主函数不写
    }

    @Test
    public void show1(){
        Class C = User.class;
        for(Field f : C.getDeclaredFields()){//返回类中所定义的属性
            // 判断这个字段是否有MyField注解
            System.out.println(f);
            if(f.isAnnotationPresent(MyField.class)){//MyField.class中定义的注解是否作用在了f上
                //本例中MyField的作用范围是属性,f就是该类的属性,所以返回true

                MyField annotation = f.getAnnotation(MyField.class);//将注解实例化
                System.out.println("字段:[" + f.getName() + "], 描述:[" + annotation.description() + "], 长度:[" + annotation.length() +"]");
            }
        }
    }

}

输出结果:


java.lang.String Strings.s
字段:[s], 描述:[用户名], 长度:[12]
int Strings.i

一个注解只能只能对一个目标起作用。

本例中,由于@Target限定了该注解只对属性有用,所以所用范围就是下一个属性。只有定义String s之前使用了注解,所以在遍历所有属性时,只有访问s时打印了注解属性字段:[s], 描述:[用户名], 长度:[12]。这是isAnnotationPresent方法的作用,判断出只有s被注解了。

同理也可以看到,@Test只对紧随的一个方法有效,下一个方法需要单元测试时也需要一个@Test。


 

注解的使用需要配合Spring Boot。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值