您的位置:首页 > 编程语言 > Java开发

java注解机制

2015-08-12 21:11 537 查看
注解:

通俗的意思是为程序的元素(类、方法、成员变量)加上更直观更明了的说明(比如 @Override),这些说明信息是与程序的业务逻辑无关,并且是供指定的工具或框架使用的。

基本原理

通过Java的反射机制相关的API来访问annotation信息。

首先加载使用注解的类,得到class类。

然后再得到类相应的方法,成员变量。

再调用相应的类、方法、成员变量的对象的isAnnotationPresent(注解的class)方法判断是否使用了注解。

再通过调用相应的类、方法、成员变量的对象的getAnnotation注解的class)得到相应的注解的对象

再操作注解对象完成相应的逻辑。

自定义

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Anno {
String hello();
String say();
int sum() default 18;
}


最上面的一部分注解叫做元注解,就是注解的注解

@Target 指的是这个注解可以用在什么地方:

/**类和接口*/
TYPE,
/** 成员变量*/
FIELD,
/** 方法*/
METHOD,
/** 参数声明 */
PARAMETER,
/** 构造器 */
CONSTRUCTOR,
/** 局部变量 */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** 包 */
PACKAGE


@Retention指的是这个注解的生命周期

/**
* 如果Retention成员取值为SOURCE,表明该注解只存在源代码当中,在编译的时候会被编译器丢掉。
*/
SOURCE,
/**
* 表示注解会被存到字节码文件.class中,但是虚拟机载入class文件的时候不会将注解导入,因此运行时无法得到。如果不在注解中使用Retention指定,则默认的保留策略为CLASS。(如:JDK内置系统注解
Override 重写
Deprecated 表示该方法或者类过期了 不鼓励用
SuppressWarnings 此注解能告诉Java编译器关闭对类、方法及成员变量的警告。)
*/
CLASS,
/**
* 不仅保存到class文件,还会被虚拟机载入内存,因此在运行的时候可以使用这些注解。
*/(如:Spring中@Autowried)
RUNTIME


@Inherited 表示子类可以继承(不能是接口)父类的注解

@Documented 表示生成doc文档的时候会包含这个注解

@interface 是定义注解的关键字

String hello();//成员变量
String say();//成员变量
int sum() default 18; //成员变量 给了默认值


注意:成员变量只能是 基本类型、String、class、enum、Annotation和以上类型的数组,而且必须是无参数、不能抛出异常。

如果只有一个的时候就只能是 String value();

public class Test3 {

private String name;

@Anno(hello = "hello", say = "world")
public String test(){
return null;
}

public static void main(String[] args) {
try {
Class c = Class.forName("com.hlj.Test3");

Method[] ms = c.getMethods();
for (Method method : ms) {
boolean is = method.isAnnotationPresent(Anno.class);
if(is){
Anno anno = method.getAnnotation(Anno.class);
}
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


反射基本知识

反射就是指在程序运行的过程中,对于每一个类都可以动态的获取他的成员变量,方法,以及构造方法的一些信息。

public class Main {

public static void main(String[] args) {

User user = new User();

Class c = user.getClass();
//=====================获得属性======================
Field declaredFields[] = c.getDeclaredFields();//包括private
Field fields[] = c.getFields();//不包括private

for (int i = 0; i < fields.length; i++) {
System.out.println(fields[i]);
}
System.out.println("------------------------");
for (int i = 0; i < declaredFields.length; i++) {
System.out.println(declaredFields[i]);
}

//=====================获得方法======================

Method method[] = c.getMethods();//包括父类的方法
Method declaredMethod[] = c.getDeclaredMethods();//自己的所有方法

for (int i = 0; i < method.length; i++) {
System.out.println(method[i]);
}
System.out.println("------------------------");
for (int i = 0; i < declaredMethod.length; i++) {
//System.out.println(declaredMethod[i].getReturnType().getName()); 得到返回的类型
//System.out.println(declaredMethod[i].getName());//得到方法名字
if(declaredMethod[i].getParameterTypes().length>0){
System.out.println(declaredMethod[i].getParameterTypes()[0]);//得到参数类型
}
}
//=====================获得构造方法======================

Constructor con[] = c.getConstructors();
Constructor declaredCon[] = c.getDeclaredConstructors();

for (int i = 0; i < con.length; i++) {
System.out.println(con[i]);
}
System.out.println("------------------------");
for (int i = 0; i < declaredCon.length; i++) {
System.out.println(declaredCon[i]);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: