Java-注解(@Annotation)

简介: 注解是插入到代码中的元数据,JDK5.0以后的版本引入。注解必须有编译器或者虚拟机来解析它,才能发挥自己的作用,它可以生成文件,可以执行编译时进行测试和验证格式等等。因为本质上,注解是一种特殊的接口,程序可以通过反射来获取指定程序元素的注解对象,然后通过注解对象来获取注解里面的元数据。 注解的作用: 1.编写文档:通过代码里标识的元数据生成文档; 2.代码分析:通过代码里标识的元数据对代码进行分析; 3.编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查;

一、缘由


   上篇也提到过要开spring cloud系列,但是避免不了就是spring boot,那针对这个我们首先要明白的就是spring boot启动到底帮我做了那些事,明白这些我们后面使用起来的时候就会得心应手,但是你会发现一个问题,那就是spring boot就是通过这些注解去加载的,所以这个地方我要来聊聊注解,当然spring也好多都是注解去实现的,这样我们就要更改明白注解到底是帮我们做了哪些事。


二、什么是注解以及注解的作用(Annotation):


   注解是插入到代码中的元数据,JDK5.0以后的版本引入。注解必须有编译器或者虚拟机来解析它,才能发挥自己的作用,它可以生成文件,可以执行编译时进行测试和验证格式等等。因为本质上,注解是一种特殊的接口,程序可以通过反射来获取指定程序元素的注解对象,然后通过注解对象来获取注解里面的元数据。

   注解的作用:

   1.编写文档:通过代码里标识的元数据生成文档;

   2.代码分析:通过代码里标识的元数据对代码进行分析;

   3.编译检查:通过代码里标识的元数据让编译器能实现基本的编译检查;


二、注解的类型


   1.内置注解

   @Override:表示当前的方法可以覆盖父类中的方法;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

   @Deprecated:用于标注该方法已经过时,当程序员调用的时候,编译器会发生警告的信息;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

  @SuppressWarnnings:用于关闭不当的编译器警告;

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

 内部有个string数组,简单的说一下改数组接收的几个常用的几个参数:

  1.deprecation:使用了由@Deprecated修饰的类或方法时的警告;

  2.unchecked:执行了未检查的转换时的警告;

  3.path:在类路径、源文件路径等中有不存在的路径时的警告;

  4.all:所有情况的警告;

  5.剩下的参考http://www.cnblogs.com/fsjohnhuang/p/4040785.html

  接下来简单的介绍下上面3种使用的方法:

public class Person {
    @Deprecated
    public void getCountryName(){
        System.out.printf("我是地球人");
    }
}
public class ChinaPerson extends Person {
    @SuppressWarnings("deprecation")
    @Override
    public void getCountryName(){
        System.out.printf("我是中国人");
    }
}
public class Main {
    public static void main(String[] args) {
        ChinaPerson chinaPerson=new ChinaPerson();
        chinaPerson.getCountryName();
    }
}

 2.元注解

  @Target:用来约束注解可以应用到的地方:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();
}

 该注解可以接收一个ElementType数组,该类型是个枚举类型可以接收如下参数:

  1.PACKAGE:标明注解可以用于包声明;

  2.CONSTRUCTOR:标明注解可以用于构造函数声明;

  3.PARAMETER:标明该注解可以用于参数声明;

  4.METHOD:标明该注解可以用于方法声明;

  5.FIELD:标明该注解可以用于字段(域)声明,包括enum实例;

  6.TYPE:标明该注解可以用于类、接口(包括注解类型)或enum声明;

  7.LOCAL_VARIABLE:标明注解可以用于局部变量声明;

  8.ANNOTATION_TYPE:标明注解可以用于注解声明(应用于另一个注解上);

  9.TYPE_PARAMETER:标明注解可以用于类型参数声明(1.8新加入);

  10.TYPE_USE:类型使用声明(1.8新加入);

  @Retention:用来约束注解的生命周期:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value();
}

  可接收的参数如下:

  1.SOURCE:在源文件中有效,被编译器丢弃;

  2.CLASS:在class文件中有效,会被VM丢弃,当没有定义CLASS默认CLASS;

  3.RUNTIME:在运行时有效,可以通过反射机制读取注解的信息;

  @Documented:被修饰的注解会生成到javadoc中

 

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


 @Inherited:允许子类继承父类的注解,即它所标注的Annotation将具有继承性,通过使用@Inherited,可以让子类Class对象使用getAnnotations()获取父类被@Inherited修饰的注解

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

  3.自定义注解

  使用@interface自定义注解,自动继承了java.lang.annotation.Annotation接口。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型。可以通过default来声明参数的默认值。

  接下来我们做个简单的案例来体验下:

import java.lang.annotation.*;
/**
 * Created by wangt on 2018/6/17.
 */
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Table {
    String value() default "";
}
import java.lang.annotation.*;
/**
 * Created by wangt on 2018/6/17.
 */
@Inherited
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
    String value() default "";
}
/**
 * Created by wangt on 2018/6/17.
 */
@Table("sutdent")
public class StudentDto {
    @Column("id")
    private String id;
    @Column("username")
    private String name;
    public StudentDto(String id, String name) {
        super();
        this.id = id;
        this.name = name;
    }
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
 * Created by wangt on 2018/6/17.
 */
public class Test {
    public static void main(String[] args){
        StudentDto studentDto=new StudentDto("1","wtz");
        StudentDto studentDto2=new StudentDto("2","www");
        String sql = assembleSqlFromObj(studentDto);
        String sql1 = assembleSqlFromObj(studentDto2);
        System.out.println(sql);
        System.out.println(sql1);
    }
    private static String assembleSqlFromObj(Object object) {
        Table table = object.getClass().getAnnotation(Table.class);
        StringBuffer sbSql = new StringBuffer();
        String tableName = table.value();
        sbSql.append("select * from " + tableName + " where 1=1 ");
        Field[] fileds = object.getClass().getDeclaredFields();
        for (Field f : fileds) {
            String fieldName = f.getName();
            String methodName = "get" + fieldName.substring(0, 1).toUpperCase()
                    + fieldName.substring(1);
            try {
                Column column = f.getAnnotation(Column.class);
                if (column != null) {
                    Method method = object.getClass().getMethod(methodName);
                    String value = (String) method.invoke(object);
                    if (value != null && !value.equals("")) {
                        if (!isNum(column.value()) && !isNum(value)) {
                            // 判断参数是不是 in 类型参数 1,2,3
                            if (value.contains(",")) {
                                sbSql.append(" and " + column.value() + " in (" + value + ") ");
                            } else {
                                sbSql.append(" and " + column.value() + " like '%" + value + "%' ");
                            }
                        } else {
                            sbSql.append(" and " + column.value() + "=" + value + " ");
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return sbSql.toString();
    }
    public static boolean isNum(String target) {
        boolean isNum = false;
        if (target.toLowerCase().contains("id")) {
            isNum = true;
        }
        if (target.matches("\\d+")) {
            isNum = true;
        }
        return isNum;
    }
}

 这个自己想想是啥原理,,哈哈不懂问我。


四、总结


 Java的注解原理是Java的反射机制,要是自定义注解那块没有看懂的话,再去读读反射把,这是一个很重要的东西,有机会我也会写一篇反射方面的;

相关文章
|
11月前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
232 7
|
8月前
|
Java 编译器 开发者
注解的艺术:Java编程的高级定制
注解是Java编程中的高级特性,通过内置注解、自定义注解及注解处理器,可以实现代码的高度定制和扩展。通过理解和掌握注解的使用方法,开发者可以提高代码的可读性、可维护性和开发效率。在实际应用中,注解广泛用于框架开发、代码生成和配置管理等方面,展示了其强大的功能和灵活性。
203 25
|
XML Java 编译器
Java学习十六—掌握注解:让编程更简单
Java 注解(Annotation)是一种特殊的语法结构,可以在代码中嵌入元数据。它们不直接影响代码的运行,但可以通过工具和框架提供额外的信息,帮助在编译、部署或运行时进行处理。
278 43
Java学习十六—掌握注解:让编程更简单
|
11月前
|
Java 编译器 数据库
Java 中的注解(Annotations):代码中的 “元数据” 魔法
Java注解是代码中的“元数据”标签,不直接参与业务逻辑,但在编译或运行时提供重要信息。本文介绍了注解的基础语法、内置注解的应用场景,以及如何自定义注解和结合AOP技术实现方法执行日志记录,展示了注解在提升代码质量、简化开发流程和增强程序功能方面的强大作用。
391 5
|
Arthas Java 测试技术
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
Java字节码文件、组成、详解、分析;常用工具,jclasslib插件、阿里arthas工具;如何定位线上问题;Java注解
Java字节码文件、组成,jclasslib插件、阿里arthas工具,Java注解
|
JSON Java 数据库
java 常用注解大全、注解笔记
关于Java常用注解的大全和笔记,涵盖了实体类、JSON处理、HTTP请求映射等多个方面的注解使用。
365 0
java 常用注解大全、注解笔记
|
Java 编译器 程序员
Java注解,元注解,自定义注解的使用
本文讲解了Java中注解的概念和作用,包括基本注解的用法(@Override, @Deprecated, @SuppressWarnings, @SafeVarargs, @FunctionalInterface),Java提供的元注解(@Retention, @Target, @Documented, @Inherited),以及如何自定义注解并通过反射获取注解信息。
Java注解,元注解,自定义注解的使用
|
Java 编译器
Java进阶之标准注解
Java进阶之标准注解
122 0
|
Java 编译器 测试技术
|
Java 数据库连接 数据格式
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit
IOC/DI配置管理DruidDataSource和properties、核心容器的创建、获取bean的方式、spring注解开发、注解开发管理第三方bean、Spring整合Mybatis和Junit
【Java笔记+踩坑】Spring基础2——IOC,DI注解开发、整合Mybatis,Junit