反射的作用场景
反射的实质
反射是指运行时候,可以通过class获取类的属性和方法(包括了私有的方法和属性)的Java机制。
反射的使用场景举例
场景的java的jdbc连接池,spring的CGLIB 反射机制机制以及有名的动态代理机制
反射的调用方法
用这个类举例
package day05.Generic.refelt;
public class Person {
String name;
String pwd;
private Integer age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private Person(String name) {
this.name = name;
}
public Person(String name, String pwd, Integer age) {
this.name = name;
this.pwd = pwd;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", pwd='" + pwd + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public Person(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
public void setName(String name) {
this.name = name;
}
public void let(){
System.out.println("调用let方法");
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
class的获取方法
反射是在运行时候通过class来获取类的属性的,获取class有三种方法
package day05.Generic.refelt;
/***
* 获取class的三种方法
* */
public class demo2 {
public static void main(String[] args) throws ClassNotFoundException {
// 调用类的class属性
Class class1 = Person.class;
System.out.println(class1);
//调用实例化对象
Person person=new Person("lin","111");
Class class2=person.getClass();
System.out.println(class2);
//按照类的路径
Class class3 = Class.forName("day05.Generic.refelt.Person");
System.out.println(class3);
}
}
使用class实例化对象
在获取了class之后,就可以直接用class来实例化对象了,也可以用Filed或者Method类来调用类的属性和方法
package day05.Generic.refelt;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/***
* 反射是动态地,使用放射可以根据类获取类地属性喝方法,
* 一个class代表一个实例
* */
public class demo {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
/* Person person=new Person("lin","1111");
person.let();*/
//使用反射调用私有构造器实例化对象
Class z=Person.class;
Constructor constructor =z.getDeclaredConstructor(String.class);
constructor.setAccessible(true);
Object o = constructor.newInstance("lin");
Person p = (Person) o;
System.out.println(p);
/*Field age = z.getDeclaredField("age");
age.set(13,"age");*/
//使用放射获取对象的私有的属性值
Person person2 =new Person("lin","1234",12);
Field field = z.getDeclaredField("age");
field.setAccessible(true);
Integer age = (Integer) field.get(person2);
System.out.println(age);
//使用反射调用私有方法
Method method = z.getDeclaredMethod("let");
method.setAccessible(true);
method.invoke(p);
}
}
动态代理机制
简单地用反射实现动态代理机制,动态代理机制简单的思路就是提供一个工具,作为代理,外界无法直接调用被代理对象,只能通过代理对象,可以减少系统的耦合度。代理分为静态代理和动态代理,使用动态代理是在运行时感知代理对象,而不是静态代理的编译时候。
package day05.Generic.refelt.dynamicproxy;
//公开接口,由继承的接口的类实现方法的细节
public interface Human {
String getBlief();
void eat(String food);
}
package day05.Generic.refelt.dynamicproxy;
public class SuperMan implements Human{
@Override
public String getBlief() {
return "I can fly";
}
@Override
public void eat(String food) {
System.out.println("吃"+food);
}
}
package day05.Generic.refelt.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**动态创建代理对象
*
* ***/
public class ProxyFactory {
//返回代理对象
public static Object getInstance(Object object){
MyInvocationHandler myInvocationHandler=new MyInvocationHandler();
myInvocationHandler.bind(object);
return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),myInvocationHandler);
}
}
class MyInvocationHandler implements InvocationHandler{
private Object object;
/**
* 获取对象
* **/
public void bind(Object object){
this.object=object;
}
//调用代理类方法时候会自动调用该方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//代理对象被调用的方法
Object value = method.invoke(object,args);
return value;
}
}
package day05.Generic.refelt.dynamicproxy;
public class ProxyTest {
public static void main(String[] args) {
SuperMan superMan=new SuperMan();
Human object = (Human) ProxyFactory.getInstance(superMan);
object.getBlief();
object.eat("面包");
}
}