一.注解的写法
@name[(信息,可有可不有)]
二.注解写在哪里
放在类上面 属性上面 方法上面 构造方法上面 参数前面
三.注解的作用
1.充当注释的作用(仅仅是文字的说明)
2.用来做代码的检测验证
3.可以携带一些内容(信息)
四.java中写好的注解
@Deprecated 方法已废弃(注释)
@override 方法重写(检测)
@SuppressWarnings({String类型的数组})
unused 变量未使用
serial 序列化的版本号
rawTypes 没用写泛型
五.注解可以携带信息,也可以不携带,但只能是如下类型;
1.基本数据类型
2.String 字符串
3.枚举类型
- 数组[]类型
5.注解类型
六.如何自己描述一个注解类型
1.通过@interface定义一个新的注解类型
2.发现与接口非常相似(可以利用接口的方式来记忆注解)
可以描述抽象方法,方法的返回值必须要有,只能是上面哪些
可以描述属性(比较少见,不推荐使用)
public @interface Annotation {
}
3.我们自己定义的注解想要拿来用,必须做很多细致的说明(需要利用java提供的元注解来说明)
元注解(也是注解,不是拿来用的,而是拿来说明注解的)
3.1@Target({ElementType.METHOD,ElementType.FIELD,ElementType.CONSTRUCTOR,...})描述当前的这个注解可以放置在哪里写
3.2@Retention(RetentionPolicy.RUNTIME)描述当前的注解存在什么作用域中
源代码文件--->编译--->字节码文件--->加载---->内存执行
SOURCE------------------CLASS---------------------RUNTIME
3.3@Inherited描述当前注解是否能被子类对象继承
3.4@Document描述这个注解能否被文档记录
4.自己使用注解
package annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR,ElementType.FIELD})
//写一个方法方法名尽量写value,这样得到注解的时候可以不写方法名
public @interface Annotation {
String value();
String test();
}
package annotation;
public class test {
@Annotation(value ="ABC",test="aaa")
private String name;
}
如何解析注解内携带的内容(反射机制)
注解应用场景
六.反射解析注解+注解应用
1.获取属性上的注解的信息
package annotation;
public class Person {
@MyAnnotation(value = {"abc","aaa"})
private String name;
}
package annotation;
//import java.lang.annotation.MyAnnotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class test {
public static void main(String[] args) {
test test=new test();
test.getFieldAnnotation();
}
/**
* 利用反射机制获取属性上的注解的信息
*/
public void getFieldAnnotation(){
//首先获取那个写了注解的类
Class clazz=Person.class;
//找到你写了注解的那个属性
try {
Field name=clazz.getDeclaredField("name");
//通过属性获取注解对象
//=============================================比较low的方法,通过对象直接调用方法,且不通用
// MyAnnotation a=name.getAnnotation(MyAnnotation.class);
// String[] values= a.value();
// for (String value:values) {
// System.out.println(value);
// }
//===============通过反射来执行方法
Annotation a=name.getAnnotation(MyAnnotation.class);
//获取自定义的注解类
Class aclazz=a.getClass();
//获取value方法
Method amethod=aclazz.getMethod("value");
String[] values=(String[]) amethod.invoke(a);
for (String value:values) {
System.out.println(value);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
效果图:
效果.PNG
2.获取方法上的注解的信息,同上.
3.设计一个方法传入一个字符串,返回一个对象,且对象已经赋值
package annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class MySpring {
/*
* 设计一个方法,给一个类名,返回一个对象,对象内的属性值存在着
*
* */
public static Object getBean(String className){
Object object=null;
try {
Class clazz=Class.forName(className);//要求参数是类全名
//1.通过clazz创建一个对象
//找到无参的构造方法
Constructor con=clazz.getConstructor();
object=con.newInstance();
//3.将对象内的所有属性自动赋值,DI
Annotation a=con.getAnnotation(MyAnnotation.class);
Class aclazz=a.getClass();
//获取value方法
Method amethod=aclazz.getMethod("value");
String[] values=(String[]) amethod.invoke(a);
// Field[] fields=clazz.getFields();
Field[] fields=clazz.getDeclaredFields();
// for (String value:values) {
/*
*赋值,找到那个对应的属性,
* 可以直接通过Field[] fields=clazz.getFields();
* 但这种方式没有通用性,所以可以通过set方法赋值
*/
int i=0;
for (Field field:fields) {
//获取属性名
String fieldName=field.getName();
//手动拼接字符串,拼接属性对应的set方法名,StringBuilder性能比String拼接好;
StringBuilder setMethodName=new StringBuilder("set");
setMethodName.append(fieldName.substring(0,1).toUpperCase());//属性首字母大写拼接
setMethodName.append(fieldName.substring(1));//其余部分拼接
//获取field对应的属性类型
Class fieldType=field.getType();
// System.out.println(fieldType.getName());
//获取set方法
Method method=clazz.getMethod(setMethodName.toString(),fieldType);
/**
* method.invoke(object,value);
*小bug只能处理String类型的数据
* */
Constructor conv=fieldType.getConstructor(String.class);//通过包装类的String构造方法
method.invoke(object,conv.newInstance(values[i]));//将String转成属性的类型
i++;
}
// }
} catch (Exception e) {
e.printStackTrace();
}
return object;
}
}
总结:
Annotationee.PNG
网友评论