注解的基础
注解的定义: Java的文件叫做Annotation 使用@interface表示
元注解: @interface上面按需要注解上一些东西包括@Retention,@Target,@Document,@Inherited四种
注解的保留策略:
1. @Retention(RetentionPolicy.SOURCE) // 注解仅存在于源码中,在class字节码文件中不包括
2. @Retention(RetentionPolicy.CLASS) // 默认的保留策略。注解会在class字节码文件中存在,但运行时无法获得
3. @Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码文件中存在,但运行时可以通过反射获取到
注解的作用目标
@Target(ElementType.TYPE) // 接口, 类, 枚举, 注解
@Target(ElementType.FIELD) // 字段, 枚举的常量
@Target(ElementType.METHOD) // 方法
@Target(ElementType.PARAMETER) // 方法参数
@Target(ElementType.CONSTRUCTOR) // 构造函数
@Target(ElementType.LOCAL_VARIABLE) // 局部变量
@Target(ElementType.ANNOTATION_TYPE)// 注解
@Target(ElementType.PACKAGE) // 包
注解包含在javadoc中
@Documentned
注解可以被继承
@Inherited
注解解析器: 用来解析自定义注解
### 如何声明注解
示例:
/**
* 自定义注解
* @author gssznb
*
*/
@Documented
@Inherited
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Init {
public String value() default "hello";
}
成员变量是可以通过 default 来指定一个默认值的
最后我们需要知道
1. 成员类型是受限制的。合法的类型包括基本的数据类型,以及String, Class, Annotation, Enumeration
2. 如果注解只有一个成员,则成员名必须取名为 value(), 在使用时候可以忽略成员名和赋值号。
3. 注解类可以没有成员,没有成员的注解成为标识注解。
自定义注解:
package cn.fllday;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义注解
* @author gssznb
*
*/
@Documented
@Inherited
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Init {
public String value() default "hello";
}
创建数据模型并使用注解
package cn.fllday;
/**
* User.java
* 数据模型中使用注解
* @author gssznb
*
*/
public class User
{
private String name;
private String age;
public String getName()
{
return name;
}
@Init(value = "liang")
public void setName(String name)
{
this.name = name;
}
public String getAge()
{
return age;
}
@Init(value = "23")
public void setAge(String age)
{
this.age = age;
}
}
通过反射获取注解中的数据
package cn.fllday;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 使用构造工厂当作 注解解析器
*
* @author gssznb
*
*/
public class UserFactory {
public static User create() {
User user = new User();
// 获取User类中的所有方法。 (getDeclareMethods)
Method[] methods = User.class.getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Init.class)) {
Init init = method.getAnnotation(Init.class);
try {
System.out.println(init.value());
method.invoke(user, init.value());
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
}
return user;
}
}
调用方法。和打印值
package cn.fllday;
public class Test {
public static void main(String[] args) {
User u = UserFactory.create();
System.out.println(u.getName());
System.out.println(u.getAge());
}
}
liang
23
liang
23