Java 使用注解Annotation
目录
注解的作用
Java内置注解
自定义注解
使用自定义注解
利用反射读取注解信息
注解的作用
注解的英文是Annotation,可以以为注释、注解。但是我们习惯称其为“注解”,因为,他不仅有注释的功能,还有其他功能。
注解不仅有“解释说明(注释)”的功能,还能被其他其他class文件读取到,让其他class进行某些操作。
Java内置注解
package lixin.gan;
import java.util.Date;
public class InnerAnnotation {
/*
* Java内置有多个注解,比如@Override, @Suppresswarning, @Deprecated....
*
* @Override 表示重写父类中的同名方法,如果父类中没有该同名方法,则会提示编译错误
* @SuppressWarnings 可以设置警告的等级,当所处的类或者方法中出现了对应的警告时,警告会被忽略
* @Deprecated 表示的是不推荐使用
*/
@Override
public String toString() {
return "hello world";
}
@Deprecated
public void test() {
Date d = new Date();
d.getMinutes();
}
public void demo1() {
int a = 0;
}
@SuppressWarnings("all")
public void demo2() {
// 相对于demo1而言,这里定义了变量a,但是没有使用,也不会出现警告
int a = 0;
}
}
自定义注解
要自己定义注解,可以看一下Java内置的注解是怎么写的,以SuppressWarnings为例:
package java.lang;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
String[] value();
}
依葫芦画瓢,我们可以写出我们自己的注解:
package lixin.gan;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* @Target(value={....})是指,该注解可以在哪些地方使用
*/
@Target(value= {
ElementType.METHOD, // 方法处
ElementType.TYPE, // 类型处,比如class、interface
ElementType.FIELD, // 属性字段处
ElementType.PACKAGE, // 包名处
ElementType.PARAMETER // 参数的地方
})
/*
* @Retention() 表明该注解会保留在哪里
*/
//@Retention(RetentionPolicy.CLASS) 该注解会保留在class文件中
//@Retention(RetentionPolicy.SOURCE) 该注解会保留在源代码中
// 上面的两种注解,都是针对编译器可见的,但是在运行时,注解就失效了
@Retention(RetentionPolicy.RUNTIME) // 注解保留到运行时,可以保证被其他类来解析
public @interface MyAnnotation {
/**
* 定义注解的参数值, 可以有默认值;没有默认值时,使用该注解,必须提供值。
*/
String name() default ""; // 表示一个名为name的“属性”,类型是String
int age() default 0; // 表示一个名为age的“属性”, 类型是int, 默认值是0
String[] hobby() default {"basketball", "swimming"}; // 类型是String[]
String value();
// 对于value来说比较特别,如果一个注解中,只有value没有默认值,那么可以省略value,直接写值
/*
@MyAnnotation(value="hello") 等价于 @MyAnnotation("hello")
*
*/
}
使用自定义注解
这里,我们重新创建两个注解:MyTable,MyField,分别用来对表名和属性进行注解
MyTable.java
package lixin.gan.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value= {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTable {
String value();
}
MyField.java
package lixin.gan.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value= {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyField {
String columnName();
String type();
int length();
boolean canEmpty() default true;
boolean primaryKey() default false;
}
使用我们上面的两个注解,假设,现在有一个Person类,对应数据库中的person表,于是,我们就可以这样做了:
package lixin.gan.annotation;
@MyTable("Person") // 等价于@Table(value= "Person")
public class Person {
@MyField(columnName="id", type="int", length=10, primaryKey=true)
private int id;
@MyField(columnName="name", type="varchar", length=30)
private String name;
@MyField(columnName="gender", type="String", length=3)
private String gender;
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", gender=" + gender + "]";
}
}
利用反射读取注解信息
package lixin.gan.orm;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import lixin.gan.annotation.MyField;
import lixin.gan.annotation.MyTable;
public class UseReflectionReadAnnotation {
public static void main(String[] args) {
try {
Class clas = Class.forName("lixin.gan.orm.Person");
// 获取“类”所有的注解
Annotation[] annotations = clas.getAnnotations();
for (Annotation tmp : annotations) {
System.out.println(tmp);
}
// @lixin.gan.orm.annotation.Table(value=Person)
// 因为一个地方,可以使用多个注解,那么,可以通过下面这种方式来查看使用具体某个注解的信息
// 获得该类来说使用某个注解的信息
MyTable t = (MyTable)clas.getAnnotation(MyTable.class);
System.out.println(t); // @lixin.gan.orm.annotation.Table(value=Person)
System.out.println(t.value()); // Person
// 获得属性的注解,要先获得类的属性
Field f = clas.getDeclaredField("name"); // 获取字段
MyField myField = f.getAnnotation(MyField.class);
System.out.println(myField.columnName() + " -- " + myField.type() + " -- " + myField.length() + " -- " + myField.canEmpty());
// name -- varchar -- 30 -- true
/**
* 此时可以根据上面的信息,拼接sql来创建表
*/
} catch (ClassNotFoundException | NoSuchFieldException | SecurityException e) {
e.printStackTrace();
}
}
}
如需转载,请注明文章出处,谢谢!!!
浙公网安备 33010602011771号