Java中的注解

一、Java的内置注解:
注解都是接口,Java中的所有注解都有一个父接口Annotation接口。

1、@Override,表示当前的方法定义将覆盖超类中的方法。只能作用于方法,不能作用其他的类型。

2、@Deprecated,使用了注解为它的元素编译器将发出警告,注解@Deprecated是表示这段代码是不赞成使用的代码,被弃用的,过时的代码。

3、@SuppressWarnings,抑制编辑器警告信息,不让编译器显示警告。可以抑制一些不必要的警告,防止影响程序运行。
@SuppressWarnings的一些常用参数:
unchecked:未检查时的执行警告。
all:抑制所有的警告
path:抑制可能出现的路径不存在的警告。
serial: 抑制序列化出现的警告。
fallthorough: 抑制使用switch…case…语句时,某一个case之后没有break掉出现的警告。

例:

@SuppressWarnings("unchecked")
class MyStack<T>{
    private T[] elements;
    private int top;

    public MyStack(){
        elements = (T[])new Object[10];
    }
}
//这里的@SuppressWarnings表示需要抑制所修饰代码块的警告
//("unchecked")表示需要抑制的警告是未检查时的执行警告,也就是泛型数组转换时的警告

这三个内置注解都是java.lang包中的注解。
除了这三个之外还有四个内置注解被称为是元注解,用于修饰注解。这四个注解都是java.lang.annotatition包中的注解

1、@Target,表示该注解可以用于什么地方,该注解有一个ElementType参数,用于表示注解作用的类型。使用时必须要加上参数来修饰注解的作用类型。
可能的ElementType参数有:
ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
ElementType.CONSTRUCTOR 可以给构造方法进行注解
ElementType.FIELD 可以给属性进行注解
ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
ElementType.METHOD 可以给方法进行注解
ElementType.PACKAGE 可以给一个包进行注解
ElementType.PARAMETER 可以给一个方法内的参数进行注解
ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举

2、@Retention,表示注解的作用域,该注解用RetentionPolicy参数来表示注解可以作用的作用域。使用时用参数来标记注解的作用域。
RetentionPolicy.SOURCE 注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视。
RetentionPolicy.CLASS 注解只被保留到编译进行的时候,它并不会被加载到 JVM 中。
RetentionPolicy.RUNTIME 注解可以保留到程序运行的时候,它会被加载进入到 JVM 中,所以在程序运行时可以获取到它们。

3、@Document,该元注解用于表示当前注解存在于用户文档中。

4、@Inherited,该元注解用来表示所修饰的注解是可继承的。
例:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
//@Inherited表示该注解是可以继承的,即该注解修饰部分的子类是依然可以继承的
//如果没有@Inherited元注解修饰则子类不能继承。
@interface Inheritable{
    String name();
}

@Inheritable()
class ClassFather{
    public ClassFather(){
        System.out.println("ClassFather: "+ClassFather.class.isAnnotationPresent(Inheritable.class));
    }
}
//isAnnotationPresent(注解名.class)该方法是用来检验class对象里是否含有某个特定注解。

class ClassSon extends  ClassFather{
    public ClassSon(){
        System.out.println("ClassSon:" +ClassSon.class.isAnnotationPresent(Inheritable.class));
    }
}

最后输出的结果都是true,说明@Inherited修饰的注解是可以继承的。

二、自定义一个Java的注解:
自定义注解的方法:
因为注解是一种特殊的接口,所以要用interface
“@interface 注解名”然后在“{}”编写注释,如果需要对自定义的注解进行修饰,那么在“@interface 注解名”的前面用元注解对自定义注解来进行修饰。
例:自定义一个注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
//@Target(ElementType.TYPE)表示该注解用于一个类型,比如类、接口、枚举
//@Retention(RetentionPolicy.RUNTIME)表示该注解可以保留到程序运行的时候。
@interface Inheritable{
    String name();
}

上边就是我们自定义的一个名为Inheritable的一个注解,在注解的里边包含有注解的名字。我们用元注解来规定出我们现在自定义的注解的作用类型是用于修饰类,作用域是保留到程序运行的时候。
注意:自定义注解必须要用@Target和@Retention这两个元注解来为自定义的注解规范出它的作用类型和作用域!
String name()当中,String表示返回值的类型,name是方法名,当前注解使用时需要传入的参数名。
例:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
    String name();
}

@MyAnnotation(name="类")
class Class1{

}

@MyAnnotation(name="接口")
interface interface1{

}

上述代码,就是示例了注解中的元素的使用,可以根据注解修饰的类型来为注解中传入不同的参数。

三、在反射中使用注解:
获取class对象的三种方式:
1 new 对象.getClass()
2 类名.Class
3 Class.forName(类的全限定名)

获取注解的方法:
getDeclaredAnnotations() 获取该类型中的所有的注解

注意:getDeclaredAnnotations()返回的是一个Annotation类型的数组!
getAnnotation(class对象)获取类的指定的注解
method.getDecalaredAnnotations() 获取某一个方法上的注解

例题:对于Student类,被两个注解所修饰
1自定义baseInfo注解,包含address和id信息,
自定义personalInfo注解,包含name、age、gender三个信息
2分别使用两个注解作用于类,方法上
3获取类、方法所对应的注解
4处理获取的各成员的注解信息,比如baseInfo b = (baseInfo)annotation,
System.out.println(“姓名:” +b.name+ “年龄:”+b.age+" 性别:"+b.gender)

student类

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface baseInfo{
    String address();
    int id();
}

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface personInfo{
    String name();
    int age();
    String gender();
}

@personInfo(name="java", age=13, gender = "male")
@baseInfo(address = "shannxi", id=1001)
class Student{

    private void eat(){
        System.out.println("I'm a pig");
    }

    @personInfo(name="xiaohua", age=18, gender = "female")
    @baseInfo(address = "shannxi", id=1123)
    public void eat(String food){
        System.out.println("I'm a pig, I love "+food);
    }

    protected void sleep(){
        System.out.println("I'm a kaola");
    }

}

提取:

//获取当前类的class对象
Class cla = Student.class;

//获取当前类的所有注解
Annotation[] annotations = cla.getDeclaredAnnotations();
for(Annotation a: annotations){
    if(a instanceof baseInfo){
        System.out.println("address: "+((baseInfo) a).address() + " id: "+((baseInfo) a).id());
//因为数组中都是Annotation的元素,而baseInfo是属于Annotation的子类。
//故需要类型转换来转换为baseInfo类型。        
    }else if(a instanceof personInfo){
         System.out.println("name: "+((personInfo) a).name() +" age: "+((personInfo) a).age()+ " gender: " +((personInfo) a).gender());
    }
}
//用instanceof来判断提取的所有注解中我们需要的注解。

 //获取指定类型的注解
Annotation annotation = cla.getAnnotation(baseInfo.class);
baseInfo b = (baseInfo)annotation;
System.out.println("address:" +b.address()+" id: "+b.id());

//获取某一个方法的注解
Method[] methods = cla.getDeclaredMethods();
for(Method m: methods){
    System.out.println(m);
}
Method method = cla.getMethod("eat",String.class);
Annotation[] annotations1 = method.getDeclaredAnnotations();
for(Annotation a: annotations1){
    if(a instanceof baseInfo){
        System.out.println("address: "+((baseInfo) a).address() + " id: "+((baseInfo) a).id());
    }else if(a instanceof personInfo){
         System.out.println("name: "+((personInfo) a).name() +" age: "+((personInfo) a).age()+ " gender: " +((personInfo) a).gender());
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值