1.什么是反射?
反射允许对成员变量,成员方法和构建方法的信息进行编程访问。
2.如何获取Class对象
- Class.forName(“全类名”); 源代码阶段使用,Java文件
- 类名.class 加载阶段,class文件
- 对象.getClass(); 运行阶段,对象已经生成。{A a = new A();}
//第一种方式
//全类名: 包名 + 类名
//最为常用的
Class<?> aClass = Class.forName("com.dome01.KunKun.java");
//第二种方式
//一般更多是当做参数进行传递
Class<KunKun> aClass1 = KunKun.class;
//第三种方式
//当我们已经有了这个类的对象时,才可以是使用。
KunKun kunKun = new KunKun();
Class aClass2 = kunKun.getClass();
通过反射能够对成员变量,成员方法和构造方法的信息进行编程访问。
以构造方法为例,演示反射的用法。
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
public class Cline {
public static void main(String[] args) throws Exception {
Class aClass = Class.forName("com.dome02.Student");
//1.获取所有公共构造方法
Constructor[] cons = aClass.getConstructors();
for (Constructor con : cons) {
System.out.println(con);
}
System.out.println("==================");
//2.获取所有构造方法
//Declared 正式宣布的,公开声明的
Constructor[] allCons = aClass.getDeclaredConstructors();
for (Constructor allCon : allCons) {
System.out.println(allCon);
}
System.out.println("==================");
/*
3.获取单个公共构造方法
public Constructor<T> getConstructor(Class<?>... parameterTypes)
需传入对应的参数类型的字节码
*/
Constructor constructor = aClass.getConstructor(String.class,int.class,String.class);
System.out.println(constructor);
//4.获取单个构造方法
System.out.println("==================");
Constructor declaredCons = aClass.getDeclaredConstructor(String.class,int.class);
System.out.println(declaredCons);
//拿到该构造方法后能够对其编码获取其他信息
//5.获取该构造方法的修饰符
System.out.println("获取该构造方法的修饰符");
int modifiers = declaredCons.getModifiers();
System.out.println(modifiers);
//6.获取该构造方法的参数
System.out.println("获取该构造方法的参数");
Parameter[] parameters = declaredCons.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}
//7.通过该构造方法创建对象
//设置该私有构造方式访问权限,能够修改和访问原本无法访问的成员
declaredCons.setAccessible(true);
Student student = (Student) declaredCons.newInstance("张三",25);
System.out.println(student.getName());
}
}
若不设置访问权限,通过该方法创建的对象为私有构造器定义的对象,则会直接抛出异常
Class com.dome02.Cline can not access a member of class com.dome02.Student with modifiers “private”
3.什么是动态代理?
无侵入式的给代码增加额外的功能。动态代理是对对象已有方法的增强,不能给对象新增方法。
4.如何知道那些方法需要代理
定义一个接口,在接口中定义方法,对象实现该接口。
5.如何创建代理对象?
java.lang.reflect.Proxy 类中提供了为对象产生代理对象的方法:
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)
/**
参数一:指定用那个类加载器,去加载生成的代理类。(即需要代理的对象的类加载器,通过获得对象的字节码来过的类加载器)
参数二:指定接口,指定代理有哪些方法。
参数三:指定生成的代理对象要干什么事情
*/
new InvocationHandler(){
public Object invock(Object proxy,Method method,Object[]args)throws Throwable{
/**
参数一:代理的对象,一般不用修改。
参数二:要运行的方法。
参数三:调用方法时需要传入的参数。
*/
//对方法进行增强处理。
//调用对象方法,返回结果值,即被代理方法的结果值。也可对结果进行处理在返回。
return method.invoke(Object,args);
}
}