Spring-Aop学习的前提——反射+动态代理——2

继上次的总结,首先说一下如何获取私有构造函数:
通过反射获取私有构造函数
Person.java

public class Person {
    private String name;
    private int age;
    public String address;
    public Person() {
        // TODO Auto-generated constructor stub
    }
    private Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
    public void show() {
        System.out.println("show........");
    }
    public void method(String s) {
        System.out.println("method  "+s);
    }
    public String getString(String s,int i) {
        return s+"==="+i;
    }
    private void function() {
        System.out.println("function");
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
    }
}

测试类:

//不加con.setAccessible(true);报错:java.lang.IllegalAccessException:非法的访问异常
        Constructor con = c.getDeclaredConstructor(String.class,int.class);
        con.setAccessible(true);//值为true指示反射的对象在使用时候取消java语言访问检查
        Object object = con.newInstance("嘿嘿",20);
        System.out.println(object);

接下来说一下如何获取成员变量并进行赋值:

Class c = Class.forName("Reflect.Person"); //带包的全路径
        Field[] fields = c.getFields();  
        for (Field field : fields) {
            System.out.println(field);
        }

以上获取的成员变量只是public修饰的。
获取全部的成员变量:

Field[] fields = c.getDeclaredFields(); //获取全部的变量
        for (Field field : fields) {
            System.out.println(field);
        }

以上两种方法是获取全部的变量,接下来说一下如何获取单个变量并进行使用:
访问公有属性

//获取address并对其赋值  address是public修饰的
        Field addressFiled = c.getField("address");
        //通过无参构造方法创建对象
        Constructor con = c.getConstructor();
        Object obj = con.newInstance();
        //addressFiled.set(obj, value):给obj这个对象的addressField这个属性设置值等于value
        addressFiled.set(obj, "济南");

这个地方的赋值比较难理解,addressFiled.set(obj, value);这句代码的意思是给obj这个对象的addressFiled变量赋值为value。
访问私有属性:

//访问私有的name属性
        Field nameField = c.getDeclaredField("name");
        nameField.setAccessible(true);
        nameField.set(obj, "张三");

以上是获取构造器和属性,还剩获取所有方法,原理类似于获取构造器和变量。
获取公有的方法:

Method[] methods = c.getMethods();//获取自己的公共方法,包括父类的公共方法
        for (Method method : methods) {
            System.out.println(method);
        }

经过测试发现,里面的公有方法不仅是Person类里的公有方法,而且包括Person父类Object里的公有方法,那如何获取Person类自身的构造方法呢?

Method[] methods = c.getDeclaredMethods();//获取自己的所有方法
        for (Method method : methods) {
            System.out.println(method);
        }

接下来是获取单个方法(这里分成无参无返回值、有参无返回值、有多个参数,有返回值、和私有方法四个方面来讲,这四个方面也基本覆盖了我们类定义的方法)
首先我们构造出无参对象:

Constructor con = c.getConstructor();
        Object obj = con.newInstance();

首先看一下获取无参无返回值的show()方法:

Method m1 = c.getMethod("show");
m1.invoke(obj);

获取有参数无返回值的方法method:

Method m2 = c.getMethod("method", String.class); 
m2.invoke(obj, "hello");

取有多个参数的有返回值得方法getString():

Method m3 = c.getMethod("getString", String.class,int.class); 
        Object objectString = m3.invoke(obj, "helloworld",50);
        System.out.println(objectString);

获取私有方法function():

Method m4 = c.getDeclaredMethod("function");
m4.setAccessible(true);
m4.invoke(obj);

以上就是我们获取各种方法的步骤,下面我们总结一下:
1.c.getMethod(name, parameterTypes) 第一个参数表示方法名字,第二个参数表示形参的class类型。
2.m1.invoke(obj, args) 第一个参数表示对象是谁,第二个参数表示调用该方法实参。
以上就是反射的基本内容,接下来会举几个关于如何利用反射的列子。

猜你喜欢

转载自blog.csdn.net/qq_39411208/article/details/81585581