Java的反射理解

反射的作用场景

反射的实质

反射是指运行时候,可以通过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("面包");
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值