注解–Annotation
注解(也被称作为元数据)为我们在代码中添加信息提供了一种形式化的方法,是我们在稍后的某个时刻非常方便的使用这些数据–java编程思想
我的理解,注解是对类以及类的信息(如属性、方法、构造器、注释)进行标注,用来描述程序所需的额外信息。
自定义注解
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface DefinedAnnotation {
public int id();
public String name() default "hh";
}
注解的定义看起很像接口的定义,和其他接口一样,但定义注解时,需要用到元注解,如@Target和@Retention,用于说明注解的使用方式以及运行级别。特别关注:注解也会编译成class文件。
元注解:
- @Target:该元注解表示可以用于什么地方
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
** ElementType 枚举类型 **
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
- @Retention,表示需要什么级别保存信息
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
** RetentionPolicy枚举类型 **
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
- @Inherited,允许子类继承父类的注解;
@Documented,用于javadoc中
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
反射获取注解信息
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DefinedAnnotation {
int id();
String name() default "hh";
String sex();
}
@DefinedAnnotation(id=1,sex = "male")
public class Person {
private int id;
private String name;
private String sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
public class Test {
public static void main(String[] args) {
Person person = new Person();
Class clazz = person.getClass();
Field[] fields = clazz.getDeclaredFields();
DefinedAnnotation annotation = (DefinedAnnotation) Person.class.getAnnotation(DefinedAnnotation.class);
System.out.println(annotation.sex()+annotation.id()+annotation.name());
//这里先留着,先研究一下spring源码后期补充,
Method[] methods = clazz.getDeclaredMethods();
Annotation[] declaredAnnotations = clazz.getDeclaredAnnotations();
for (Field field : fields) {
System.out.println(field.getName());
}
// System.out.println(annotation instanceof Person);
// for (Method method : methods) {
// System.out.println(method.getName());
// }
}
}
备注:对于如何通过反射+注解新建对象放弃挣扎,很难受
在一篇博客看到这样一段话,感觉不错,记录一下:
注解本身不做任何事情,只是像xml文件一样起到配置作用。注解代表的是某种业务意义,注解背后处理器的工作原理:首先解析所有属性,判断属性上是否存在指定注解,如果存在则根据搜索规则取得bean,然后利用反射原理注入。如果标注在字段上面,也可以通过字段的反射技术取得注解,根据搜索规则取得bean,然后利用反射技术注入。
下周看点:工厂模式,这篇注解写的不好,等研究过Spring之后再做补充