版权声明:本文为博博原创文章,未经博博允许不得转载。 https://blog.csdn.net/u013523377/article/details/72858621
一、Class
1. Class 类型的获取
- Clazz.class;
- clazz.getClass();
- Class.forName(String className);
2. 根据 Class 类型创建类实例
Class clazzType = Clazz.class;
try{
// Clazz 必需含有无参构造方法
Clazz clazzBean = (Clazz)clazzType.newInstance();
}catch(Exception e){
e.printStackTrace();
}
3. Class 加载
加载方式 | 实现 | 描述 |
---|---|---|
静态加载 | new Clazz() | 在编译过程就加载 |
动态加载 | (Class.forName(String className)).newInstance() | 运行时才加载 |
二、反射
1. 反射的基本应用
class Clazz{
public void print(String str){
System.out.print("str");
}
}
// 1. 获取类信息
Clazz clazz = new Clazz();
Class c = clazz.getClass();
try{
// 2. 获取类方法
Method m = c.getMethod("print", String.class);
// 3. 实现方法的反射操作
m.invoke(clazz, "设定输出内容");
}catch(Exception e){
e.printStackTrace();
}
2. 反射在泛型中的应用
反射操作位于编译之后,即编译后为泛型对象将失去泛型特征
ArrayList<String> list = new ArrayList<String>();
Class c = list.getClass();
try{
// 通过反射绕过编译时对插入值类型的判断
Method m = c.getMethod("add", Object.class);
m.invoke(list, 1);
}catch(Exception e){
e.printStackTrace();
}
三、注解
1. 概念理解
- 成员类型必需是原始类型 及 String,Class, Annotation, Enumeration
- 如果注解成员只有一个,则成员命名必需为 value(),在使用时可忽略成员名与赋值号(=)
- 注解类可无成员对象,称之为标识注解
// 元注解
@Target({ElementType.METHOD,ElementType.TYPE}) // 作用域
@Retention(RetentionPolicy.RUNTIME) // 声明生命周期
@Inherited // 允许子类继承,且仅继承类注解
@Documented // 生成 javadoc 时包含注解信息
// 使用@interface 定义注解
public @interface Description{
// 无参无异常的成员声明
String sex();
String author();
// 成员的默认值声明
int age() default 18;
}
作用域 | 描述 |
---|---|
@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) | 包 |
生命周期/注解分类 | 描述 |
---|---|
@Retention(RetentionPolicy.SOURCE) | 源码注解(仅源码中存在,编译后不存在) |
@Retention(RetentionPolicy.CLASS) | 编译时注解(源码与编译后均存在) |
@Retention(RetentionPolicy.RUNTIME) | 运行时注解(运行时存在,影响逻辑处理) |
2. 自定义
语法: @<注解名>(<成员名1>=<成员值>,<成员名2>=<成员值2>,…)
@Description(sex="I am boy", author="gzejia",age="25")
public class Clazz{
@Description(sex="I am boy", author="gzejia",age="25")
public String manSex(){
return "boy";
}
}
3. 注解解析
通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑
try{
// 1.使用类加载器加载类
Class c = Class.forName("...Clazz");
// 2.判断是否存在注解信息
boolean isExist = c.isAnnotationPresent(Description.class);
// 3.获取类注解信息
if(isExist){
Description d = (Description)c.getAnnotation(Description.class);
System.out.println(d.sex());
}
// 4.获取方法注解信息
Method[] ms = c.getMethods();
for(Method m : ms){
boolean isMExist = m.isAnnotationPresent(Description.class);
if(isExist){
Description d = (Description)m.getAnnotation(Description.class);
System.out.println(d.author());
}
}
// 获取注解信息方式二(以获取方法注解信息为例)
for(Method m : ms){
Annotation[] as = m.getAnnotations();
for(Annotation a : as){
if(a instanceof Description){
Description d = (Description)a;
System.out.println(String.valueOf(d.age()));
}
}
}
}catch(Exception e){
e.printStackTrace();
}