欢迎来到刘志红的博客

别人说程序员是“搬砖”的码农,但我们知道自己是追求个性的艺术家。也许我们不会过多的在意自己的外表和穿着,但在不羁的外表下,骨子里追求着代码的美、系统的美、设计的美。
扩大
缩小

java注解

概述:

java1.5加入了注解的概念,什么是注解?注解有什么好处?

注解:java提供的一种源程序关联任何信息和任何元数据的途径和方法。

注解使代码变得简洁,例如spring中引入了大量的注解。

1.JDK中的注解

@override   标识重写   

@Deprecated 标识过时

@SuppressWarnings()  忽略警告 一般IDE要警告可以自动帮我们生成

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) //忽略警告的类型
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

2.第三方注解

例如spring,mybatis中的一些注解

3.注解的类型

 1.源码注解  只在源码显示,编译时会丢失

 2.编译注解  编译时候会记录到class中,运行时忽略。例如JDK的三个注解

 3.运行注解  运行时候存在可以通过反射读取

4.自定义注解

 1.元注解

元注解 描述
@Target

表示该注解可以用于什么地方。可能的ElementType参数包括:

CONSTRUCTOR:构造器的生命

FIELD:域声明(包括enum实例)

LOCAL_VARIABLE:局部变量声明

METHOD:方法声明

PACKAGE:包声明

PARAMETER:参数声明

TYPE:类、接口(包括注解类型)和enum声明

ANNOTATION_TYPE:注解声明(与TYPE的区别?,专门用在注解上的TYPE)

TYPE_PARAMETER:Java8

TYPE_USE:Java8

@Retention

表示需要在什么级别保存该注解信息。可选的RetentionPolicy参数包括:

SOURCE:注解将在编译器丢弃

CLASS:注解在class文件中可用,但会被VM丢弃

RUNTIME:VM将在运行期也保留注解,因此可以通过反射机制读取注解的信息

@Documented 标识型注解:生成javadoc的时候会包含注解信息
@Inherited 标识型注解:允许子类继承父类中的注解(用在子类与父类之间,接口和实现类之间无效)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

java8新增元注解@Repeatable

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    /**
     * Indicates the <em>containing annotation type</em> for the
     * repeatable annotation type.
     * @return the containing annotation type
     */
    Class<? extends Annotation> value();
}

注意java8新增(可重复注解和类型注解)详情请查看博主的java8新特性

2.自定义注解的语法要求

 1 package simple;
 2 import java.lang.annotation.*;
 3 /**
 4  * @ClassName MyAnno
 5  * @Description
 6  * @Author 刘志红
 7  * @Date 2019/3/28
 8  **/
 9 //下面四个为元注解
10 @Target({ElementType.METHOD,ElementType.FIELD})//注解的作用域
11 @Retention(RetentionPolicy.RUNTIME)  //定义注解的类型
12 @Inherited   //标识该注解可以被继承
13 @Documented  //将注解包含在javadoc中
14 public @interface /*前面整体为定义注解的关键字*/ MyAnno {
15     //注解成员以无参无异常的方式声明 用default指定默认值
16     //成员的类型是受限制的,合法的类型包含原始类型(基本数据类型)、String、Class、Annotation、Enumeration
17     //注意如果注解成员只有一个的时候,我们应该使用成员名value(这是一个规范,用别的也不报错),使用的时候可以省略成员名和= 直接写值即可。
18     String desc();
19     String author();
20     int age() default 20;
21 }

 

3.自定义注解的使用实例:通过反射获取注解信息动态的控制程序运行逻辑

简单的一个给字段用注解赋值:

package simple;
import java.lang.annotation.*;
/**
 * @ClassName MyAnno
 * @Description 自定义注解用于给字段自动复制
 * @Author 刘志红
 * @Date 2019/3/28
 **/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface  MyAnno {
    String value() default "xiaoqiang";
}
View Code
package simple;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * @ClassName Handler
 * @Description   反射解析类中注解
 * @Author 刘志红
 * @Date 2019/3/28
 **/
public class Handler {
    public void hand(Object o) {
        try {
            Class<?> pojo = o.getClass();
            Field[] fields = pojo.getDeclaredFields();
            for (Field f :
                    fields) {
                boolean annotationPresent = f.isAnnotationPresent(MyAnno.class);
                if (annotationPresent)
                {
                    MyAnno annotation = f.getAnnotation(MyAnno.class);
                    String value = annotation.value();
                    String name = f.getName();
                    //处理名字首字母大写可以方便构造set方法
                    String setName="set"+name.substring(0, 1).toUpperCase()+name.substring(1);
                    Method method = pojo.getMethod(setName, String.class);
                    method.invoke(o, value);
                }
            }

        }  catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}
View Code
package simple;
/**
 * @ClassName Pojo
 * @Description  使用注解的类
 * @Author 刘志红
 * @Date 2019/3/28
 **/
public class Pojo {
    @MyAnno("旺财")
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
View Code
package simple;
/**
 * @ClassName Test
 * @Description
 * @Author 刘志红
 * @Date 2019/3/26
 **/
public class Test {
    public static void main(String[] args) {
        Pojo pojo=new Pojo();
        Handler handler = new Handler();
        handler.hand(pojo);
        System.out.println(pojo.getName());

    }
}
View Code

 后面会补一个简单用注解实现数据库实体类映射的例子,请继续关注。

posted on 2019-03-28 20:09  MR_程序猿刘  阅读(231)  评论(0编辑  收藏  举报

导航