反射
(将类的各个组成部分封装成为其他对象)类的成员对象封装成field对象,构造方法封装成constructor对象,成员方法封装成为method对象,就是反射机制。
对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;
获取class对象的方式
1、Class.forName(“全类名”); 多用于配置文件
2、类名.class; 通过类名的属性class获取。多用于参数的传递
3、对象.getClass(); 该方法在object类中定义。多用于对象的获取字节码的方式
Class对象功能
1、获取成员变量们
- 获取值get()
- 设置值set()
- 忽略访问权限修饰符的安全检查 setAccessible(true); // 暴力反射!!
---- 常用方法
Field[] getFields()// 获取所有public修饰的成员变量
Field getField(String name) // 获取指定名称public变量,可以用get/set方法修改值
Field[] getDeclaredField() //获取所有的成员变量
Field getDeclaredField(String name) // 获取任意指定成员变量
2、获取构造方法们
- 可用来创建对象: T newInstance()
Class personClass = Person.class;
Constructor constructor = personClass.getConstructor(String.class,int.class);
Object pereson1 = constructor.newInstance("朱连伟", 21);
---- 常用方法
Constructor<?>[] getConstructors() //获取所有public的构造函数
Constructor<T> getConstructor(class<?>...parameterTypes) // 获取指定参数类型的构造函数
Consstrucor<T> getDeclaredConstructor(class<?>...parameterTypes)
Constructor<?>[] getDeclaredConstructors()
3、获取成员方法们
- 用来执行方法 : invoke()
- 获取方法名称: getName()
---- 常用方法
Method[] getMethods()
Method getMethod(String name,class<?>...parameterType)
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name,class<?>...parameterType)
4、获取类名
personClass.getName();
总结
带declared的能获取全部的变量、方法。不带declared的只能获取public的。修改/读取private类型数据时,需要暴力反射!(xxx.setAccessible(true) //暴力反射)
注解
概念:
JDK1.5之后的;
说明程序的;
使用注解:@注解名称;
作用分类
1、编写文档:通过代码里标识的注解生成文档【生成文档doc文档】
2、代码分析:通过代码里标识的注解对代码进行分析【使用反射】
3、编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【Override】
JDK中预定义的注解
@Override
@Deprecated//表示内容已过时
@SuppressWarnings("all")//忽略警告信息。
自定义注解
本质:注解本质就是一个接口,该接口默认继承Annotation接口
属性:注解中的抽象方法
元注解:用于描述注解的注解
@Target//表示这个注解能放在什么位置上
@Retention//表示生命周期
@Documented//描述注解是否被抽取到api文档中
@Inherited//描述注解是否被子类继承
使用注解
Pro
package annotation;
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 Pro {
String className();
String methodName();
}
ReflectDemo1
public class ReflectDemo1 {
public void test(){
System.out.println("ReflectDemo1.test()");
}
}
ReflectTest
import java.lang.reflect.Method;
@Pro(className = "annotation.ReflectDemo1",methodName = "test")
public class ReflectTest {
// 不能改变任意代码的前提下。可以创建任意类的对象,可以执行任意方法
public static void main(String[] args) throws Exception {
// 获取本身的class对象
Class<ReflectTest> reflectTestClass = ReflectTest.class;
// 获取注解对象
Pro annotation = reflectTestClass.getAnnotation(Pro.class);
// 调用注解对象中定义的抽象方法(属性),获取返回值
String className = annotation.className();
String methodName = annotation.methodName();
System.out.println(className);
System.out.println(methodName);
// 创建类、执行方法
// 通过全类名获取class对象
Class clazz = Class.forName(className);
// 通过class对象获取构造方法,构造类的实例
Object obj = clazz.getConstructor().newInstance();
// 通过class对象获取方法
Method method = clazz.getMethod(methodName);
// 执行obj中的方法
method.invoke(obj);
}
}