Java内置基本注解:
在Java中内置几种了基本的注解,下面列出几种常用的注解:
1、@Deprecated:用该注解注释的程序元素,表明不鼓励程序员使用这样的元素,通常是它很危险或存在更好的选择。
2、@Override:表明当前的方法定义将覆盖超类中的方法。
3、@SuppressWarnings:表明关闭不当的编译器警告信息。
4、@Documented:表明某一类型的注释将通过javadoc和类似的默认工具进行文档化。
5、@Inherited:允许子类继承父类中的注解。
6、@Retention:表明需要在什么级别保存该注解信息。
7、@Target:表明该注解可以用于什么地方。
8、@Generated:该注解用于标记已生成的源代码,它可以用于区分单个文件中用户编写的代码和生成的代码。
9、@PostConstruct:该注解用于在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。
10、@PreDestroy:该注解作为回调通知用于各方法,以表示该实例正处于被容器移除的过程中。
11、@Resource:该注解用于标记应用程序所需要的资源。
元注解:
a. @Retention
它是被定义在一个注解类的前面,用来说明该注解的生命周期。
它有以下参数:
RetentionPolicy.SOURCE:指定注解只保留在一个源文件当中。
RetentionPolicy.CLASS:指定注解只保留在一个class文件中。
RetentionPolicy.RUNTIME:指定注解可以保留在程序运行期间。
注解的生命周期:
一个注解可以有三个生命周期,它默认的生命周期是保留在一个CLASS 文件,
但它也可以由一个@Retetion 的元注解指定它的生命周期。
a. java 源文件
当在一个注解类前定义了一个@Retetion(RetentionPolicy.SOURCE)的注解,那么说
明该注解只保留在一个源文件当中,当编译器将源文件编译成class 文件时,它不
会将源文件中定义的注解保留在class 文件中。
b. class 文件中
当在一个注解类前定义了一个@Retetion(RetentionPolicy.CLASS)的注解,那么说
明该注解只保留在一个class 文件当中,当加载class 文件到内存时,虚拟机会将注
解去掉,从而在程序中不能访问。
c. 程序运行期间
当在一个注解类前定义了一个@Retetion(RetentionPolicy.RUNTIME)的注解,那么
说明该注解在程序运行期间都会存在内存当中。此时,我们可以通过反射来获得
定义在某个类上的所有注解。
b. @Target
它是被定义在一个注解类的前面,用来说明该注解可以被声明在哪些元素前。
它有以下参数:
ElementType.TYPE:说明该注解只能被声明在一个类前。
ElementType.FIELD:说明该注解只能被声明在一个类的字段前。
ElementType.METHOD:说明该注解只能被声明在一个类的方法前。
ElementType.PARAMETER:说明该注解只能被声明在一个方法参数前。
ElementType.CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前。
ElementType.LOCAL_VARIABLE:说明该注解只能声明在一个局部变量前。
ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前。
ElementType.PACKAGE:说明该注解只能声明在一个包名前。
注解的使用分为三个过程。
定义注解-->声明注解-->得到注解
a. 定义注解
b. 声明注解
c. 得到注解
对于生命周期为运行期间的注解,都可以通过反射获得该元素上的注解实例。
1、声明在一个类中的注解
可以通过该类Class 对象的getAnnotation 或getAnnotations 方法获得。
2、声明在一个字段中的注解
通过Field 对象的getAnnotation 或getAnnotations 方法获得
3、声明在一个方法中的注解
通过Method 对象的getAnnotation或getAnnotations 方法获得
注解实例:
定义一个注解:
package com.annotationtest.learning;
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;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Description {
String Auth() default "maolei";
int size();
}
声明注解并得到注解:
package com.annotationtest.learning;
@Description(Auth="maoqingshan",size=20)
public class DescriptionTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
if(DescriptionTest.class.isAnnotationPresent(Description.class)){
Description description = (Description)DescriptionTest.class.getAnnotation(Description.class);
System.out.println(description.Auth());
System.out.println(description.size());
}
}
}
annotation与annotation之间没有继承关系,只能用在类或接口里,由于在annotation类Description里面增加了@Inherited,因此,子类可以直接继承父类中的注解
注解应用实例:
定义两个注解
1:pojo用于描述pojo类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Pojo {
String table();
2:colum用于描述pojo类的成员变量的属性
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Colum {
String columName();
boolean isNULL() default true;
String Type() default "";
}
应用以上两个注解到pojo类:
/**
* 应用注解的pojo类
* @author Administrator
*
*/
@Pojo(table = "person")
public class PersionPOJO {
public PersionPOJO() {
super();
}
@Colum(columName = "id", isNULL = false, Type = "varchar")
private String id;
@Colum(columName = "name", isNULL = false, Type = "varchar")
private String name;
@Colum(columName = "age", isNULL = true, Type = "int")
private int age;
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;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
处理注解的罗杰实现:
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
/**
* 处理注解的逻辑实现类
* @author Administrator
*
*/
public class MyJPAProcess {
public static void process(Object object) throws ClassNotFoundException {
// 所有注解
Annotation[] annotationsClass = object.getClass().getAnnotations();
Field[] fields =object.getClass().getDeclaredFields();
// 遍历注解元素
for (Annotation annotation : annotationsClass) {
if (annotation instanceof Pojo) {
System.out.println("--------处理POJO实体--------");
Pojo pojo = (Pojo) annotation;
System.out.println("存储表名:" + pojo.table());
}
}
for (Field field : fields) {
//field.setAccessible(true);
Annotation[]annotationsMethos = field.getAnnotations();
// 遍历注解元素
for (Annotation annotation : annotationsMethos) {
if (annotation instanceof Colum) {
System.out.println("--------处理Colum字段--------");
Colum colum = (Colum) annotation;
System.out.println("字段名:" + colum.columName());
System.out.println("字段类型:" + colum.Type());
System.out.println("是否能为空:" + colum.isNULL());
}
}
}
}
}
应用测试:
public class PersionDAO {
public void save(PersionPOJO persionPOJO) throwsClassNotFoundException {
MyJPAProcess.process(persionPOJO);
}
public static void main(String[] args) throws ClassNotFoundException {
PersionDAO persionDAO = new PersionDAO();
PersionPOJO persionPOJO = new PersionPOJO();
persionDAO.save(persionPOJO);
}
}
总结
注解可以看成是一个接口,注解实例就是一个实现了该接口的动态代理类。
注解大多是用做对某个类、方法、字段进行说明,标识的。以便在程序运行期间我们通
过反射获得该字段或方法的注解的实例,来决定该做些什么处理或不该进行什么处理。
注意地方:
1、注解元素可以用的类型只有:所有基本类型(int,float,boolean)、String、Class、enum、Annotation、以上类型的数组。
2、在定义元素的默认值时有限制,首先,元素不能有不确定的值,也就是说,元素必须要么具有默认值,要么在使用注解时提供元素的值;其次,对于非基本类型的元素,不能以null作为其值。
3、注解不支持继承。