java反射机制是为了动态获取类的结构,动态地调用对象的方法
java反射机制
获取类Class对象
- A.class :不会加载类,也不会执行静态代码段;
- Class.forName("cn.test.reflect.A") :要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段;
- new A().getClass() :通过对象获取class
public class TestFanshe2 {
public static void main(String[] args) throws ClassNotFoundException {
Class.forName("aboutjava.TestFanshe");
System.out.println(TestFanshe.class);
new TestFanshe();
}
}
class TestFanshe {
static{
System.out.println("静态代码段!");
}
}
我们这里可以看到,当没注释掉forName方法的时候,会输出TestFanshe类的静态方法块,但是它只是加载了,还没有链接和初始化,当运行New TestFanshe()时,不会再加载,而是直接初始化,调用<init>方法。
创建对象
//调用public的无参构造函数
Class t = Class.forName("aboutjava.TestFanshe");
t.newInstance();
//通过选择构造器创建对象
Constructor cons[] = t.getConstructors();
cons[0].newInstance();
动态代理
package aboutjava;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class TryDongtaidaili {
interface Animal {
public void makeSound(String name);
}
static class Dog implements Animal {
@Override
public void makeSound(String name) {
System.out.println("Hi," + name + ",wang,wang~~");
}
}
class Cat implements Animal {
@Override
public void makeSound(String name) {
System.out.println("Hi," + name + ",miao,miao~~");
}
}
static class AnimalProxy implements InvocationHandler {
private Object target;
public Object getInstance(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
System.out.println("方法调用前~");
result = method.invoke(target, args);
System.out.println("方法调用后~");
return result;
}
}
public static void main(String[] args) {
AnimalProxy proxy = new AnimalProxy();
Animal dogProxy = (Animal) proxy.getInstance(new Dog());
dogProxy.makeSound("dog");
}
}
动态代理主要是实现一个InvocationHandler接口和通过一个Proxy类获得一个代理。
Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
this);
Proxy通过newProxyInstance获取到代理类,三个参数分别是,类加载器、类实现的接口、链接的InvocationHandler类,这样当proxy调用方法的时候,其实就是调用了InvocationHandler类的invoke方法,并通过method对象的invoke方法调用具体方法