Java-注解(@Annotation)
一、缘由
上篇也提到过要开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 {
}
View Code
@Deprecated:用于标注该方法已经过时,当程序员调用的时候,编译器会发生警告的信息;
@Documented@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
View Code
@SuppressWarnnings:用于关闭不当的编译器警告;
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
View Code
内部有个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();
}
}
View Code
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();
}
View Code
该注解可以接收一个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();
}
View Code
可接收的参数如下:
1.SOURCE:在源文件中有效,被编译器丢弃;
2.CLASS:在class文件中有效,会被VM丢弃,当没有定义CLASS默认CLASS;
3.RUNTIME:在运行时有效,可以通过反射机制读取注解的信息;
@Documented:被修饰的注解会生成到javadoc中
@Documented@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
View Code
@Inherited:允许子类继承父类的注解,即它所标注的Annotation将具有继承性,通过使用@Inherited,可以让子类Class对象使用getAnnotations()获取父类被@Inherited修饰的注解
@Documented@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
View Code
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;
}
}
View Code
这个自己想想是啥原理,,哈哈不懂问我。
四、总结:
Java的注解原理是Java的反射机制,要是自定义注解那块没有看懂的话,再去读读反射把,这是一个很重要的东西,有机会我也会写一篇反射方面的;
欢迎大家加群:438836709,有问题可以咨询我
欢迎大家关注我微信公众号:
以上是 Java-注解(@Annotation) 的全部内容, 来源链接: utcz.com/z/390186.html