【动态代理之一】反射基础

      在理解动态代理之前,需要理解一下反射的概念和基础。

一、定义

      Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。可以理解为在运行时期获取对象类型信息的操作。传统的编程方法要求程序员在编译阶段决定使用的类型,但是在反射的帮助下,编程人员可以动态获取这些信息,从而编写更加具有可移植性的代码。

 

二、Class类

        Class这个类用于操纵一个类的属性,方法,构造器。众所周知Java有个Object类,是所有Java类的继承根源,其内声明了数个应该在所有Java类中被改写的方法,hashCode(), equals(), clone(), toString(), getClass()等。其中getClass()返回一个Class对象。Class类十分特殊。它和一般类一样继承自Object,其实体用以表达Java程序运行时的classes和interfaces,也用来表达enum、array、primitive java types(boolean, byte, char, int, long, float, double) 以及关键词void。当一个class类被加载,或者当加载器(class loader)的defineClass() 被JVM调用,JVM便自动产生一个Class类对象。

 

三、获取Class对象的三种方式

1)Class.forName("classpath"):classpath为类所在的路径。

2)object.class

3)object.getClass()

举个例子:

首先定义一个Person类

package com.csdn.reflect;

public class Person {

    private String name;

    private String address;

    private int age;

    public Person() {

    }

    public Person(String name, String address, int age) {
        this.name = name;
        this.address = address;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", age=" + age +
                '}';
    }
}

ReflectDemo

package com.csdn.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectDemo {

    public static void main(String[] args) throws Exception {

        Person p = new Person();

        testForName();

        testDotClass();

        testGetClass(p);
    }

    public static void testForName() throws Exception{

        System.out.println("=========testForName start===============");
        //也能获得一个类的类对象
        Class clazz = Class.forName("com.csdn.reflect.Person");

        output(clazz);

        System.out.println("=========testForName end===============");
    }

    public static void testGetClass(Object obj) {
        System.out.println("=========testGetClass start===============");
        //也能获得一个类的类对象
        Class clazz = obj.getClass();

        output(clazz);

        System.out.println("=========testGetClass end===============");
    }

    public static void testDotClass() {
        System.out.println("=========testDotClass start===============");

        //也能获得一个类的类对象
        Class clazz = Person.class;

        output(clazz);

        System.out.println("=========testDotClass end===============");
    }

    public static void output(Class clazz) {
        //获得传递过来的类的所有方法
        Method[] methods = clazz.getDeclaredMethods();
        for(Method m : methods) {
            System.out.println(m);
        }

        System.out.println("-----------------------------------------");
        //获得类的所有属性
        Field[] fields = clazz.getDeclaredFields();
        for (Field f : fields) {
            System.out.println(f);
        }
        System.out.println("-----------------------------------------");

        //获得类的所有的构造器
        Constructor[] cs = clazz.getDeclaredConstructors();
        for(Constructor c: cs) {
            System.out.println(c);
        }
    }
}

四、反射举例

        可以通过类对象来获取属性Field,方法Method,以及构造器Constructor,通过构造器可以用来生成新的对象,并通过反射调用来调用类方法。举个栗子:

ReflectDemo1

package com.csdn.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectDemo1 {

    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("com.csdn.reflect.Person");

        //获得类对象的一个属性
        Field field = clazz.getDeclaredField("address");
        System.out.println(field);

        //获得一个具体的方法
        Method method = clazz.getDeclaredMethod("getName", new Class[]{});
        System.out.println(method);
        Method method1 = clazz.getDeclaredMethod("setName", new Class[]{String.class});
        System.out.println(method1);

        //获得构造器
        Constructor constructor = clazz.getDeclaredConstructor(new Class[]{});
        System.out.println(constructor);

        //根据类的默认构造器来获得一个对象
        Object instance = constructor.newInstance(new Object[]{});
        //get setName method
        Method mSet = clazz.getDeclaredMethod("setName", new Class[]{String.class});
        //call method on the instance object
        Object invoke = mSet.invoke(instance, new Object[]{"lebaishi"});
        System.out.println(invoke);

        //get getName method
        Method mGet = clazz.getDeclaredMethod("getName", new Class[]{});
        //call method on the install object
        Object invoke2 = mGet.invoke(instance, new Object[]{});
        System.out.println(invoke2);
    }
}

Author:忆之独秀

Email:[email protected]

注明出处:https://blog.csdn.net/lavorange/article/details/86190050
 

 

你可能感兴趣的:(Java)