java 反射机制及动态代理

反射概述
Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。

  Java反射机制主要提供了以下功能:

在运行时构造任意一个类的对象
在运行时获取任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的方法(属性)
生成动态代理

  Class 是一个类; 一个描述类的类.
   封装了描述方法的 Method,
描述字段的 Filed,
描述构造器的 Constructor 等属性.
下面我们以student为例 一一介绍

先说获取Class对象的三种方式
1.通过类名获取 类名.class
2.通过对象获取 对象名.getClass()
3.通过全类名获取 Class.forName(全类名)

       //类名.class
        Class<ConStudent> conSC = ConStudent.class;
        System.out.print("---------类名.class---------"+"\n");
        //对象名.getClass()
        ConStudent conStudent = new ConStudent();
        Class<? extends ConStudent> conSC1 = conStudent.getClass();
        System.out.print("---------对象名.getClass()---------"+"\n");
        //Class.forName(全类名)
        Class<?> conSC2 = Class.forName("com.reflection.ConStudent");
        System.out.print("---------Class.forName(全类名)---------");

———类名.class———
静态代码:10
———对象名.getClass()———
静态代码:10
———Class.forName(全类名)———

public class ConStudent {

    public static int number = 10;
    static {
        System.out.print("静态代码:"+number+"\n");
    }
}

通过以上方式可以看出 第二第三种方式是直接调用静态代码的 从方便和效率来看 第三中方式是最好的 第一种也不错 第二种是不推荐的 个人建议 仅供参考

现在说一下 Constructor

先看一下 实体类

/**
 * Constructor
 */
public class ConStudent {

    public ConStudent(){
        System.out.print("ConStudent空参构造函数"+"\n");
    }

    public ConStudent(double score) {
        System.out.print("ConStudent有参构造函数"+"\n");
    }

    private ConStudent(int age) {
        System.out.print("ConStudent私有构造带参数"+age+"\n");
    }
    protected  ConStudent(String name){
        System.out.print("ConStudent受保护的构造参数"+name+"\n");
    }

}
private static void constructor() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        Class<?> conSC = Class.forName("com.reflection.ConStudent");
        Constructor<?>[] constructors = conSC.getConstructors();
        for (Constructor c :constructors){
            System.out.print("ReflectTest所有公有构造:"+c+"\n");
        }
        System.out.print("ReflectTest----------分割线-------------"+"\n");

        Constructor<?>[] declaredConstructors = conSC.getDeclaredConstructors();
        for (Constructor c : declaredConstructors){

            System.out.print("ReflectTest所有构造方法:"+c+"\n");
        }
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Constructor constructor = conSC.getConstructor();
        System.out.print("ReflectTest公有无参构造方法"+constructor+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Constructor<?> declaredConstructor = conSC.getDeclaredConstructor(int.class);
        System.out.print("ReflectTest私有构造方法"+declaredConstructor+"\n");
        declaredConstructor.setAccessible(true);
        Object o = declaredConstructor.newInstance(11);
        System.out.print("ReflectTest调用私有构造"+o+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Constructor<?> declaredConstructor1 = conSC.getDeclaredConstructor(String.class);
        declaredConstructor1.setAccessible(true);
        Object maoge = declaredConstructor1.newInstance("maoge");
        System.out.print("ReflectTest受保护的构造:"+maoge);

    }

输出内容

ReflectTest所有公有构造:public com.reflection.ConStudent(double)
ReflectTest所有公有构造:public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest所有构造方法:protected com.reflection.ConStudent(java.lang.String)
ReflectTest所有构造方法:private com.reflection.ConStudent(int)
ReflectTest所有构造方法:public com.reflection.ConStudent(double)
ReflectTest所有构造方法:public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest公有无参构造方法public com.reflection.ConStudent()
ReflectTest----------分割线-------------
ReflectTest私有构造方法private com.reflection.ConStudent(int)
ConStudent私有构造带参数11
ReflectTest调用私有构造com.reflection.ConStudent@14ae5a5
ReflectTest----------分割线-------------
ConStudent受保护的构造参数maoge
ReflectTest受保护的构造:com.reflection.ConStudent@7f31245a
Process finished with exit code 0

下面看一下 Filed
实体也是三个参数 代表三种权限

/**
 * Filed
 */
public class FiledStudent {
    public int age;
    private String name;
    protected double score;

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

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}
 private static void filedTest() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> filedSC = Class.forName("com.reflection.FiledStudent");
        Field[] fields = filedSC.getFields();
        for (Field f :fields){
            System.out.print("ReflectTest所有公有的参数:"+f+"\n");
        }
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Field age = filedSC.getField("age");
        Object o = filedSC.getConstructor().newInstance();
        age.set(o,11);
        FiledStudent student = (FiledStudent) o;
        System.out.print("ReflectTest获取公有参数:"+student.getAge()+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Field[] declaredFields = filedSC.getDeclaredFields();
        for (Field f :declaredFields){
            System.out.print("ReflectTest获取所有参数:"+f+"\n");
        }
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Field name = filedSC.getDeclaredField("name");
        name.setAccessible(true);
        name.set(o,"Maoge");

        System.out.print("ReflectTest获取指定的私有参数:"+student.getName()+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Field score = filedSC.getDeclaredField("score");
        score.setAccessible(true);
        score.set(o,9.8);
        System.out.print("ReflectTest获取受保护的参数:"+student.getScore());

    }

下面看 mothed

/**
 * Method
 */
public class MethodStudent{
    int age;
    String name;
    double score;

    public void showName( ){
        System.out.print("(公共)姓名:");
    }
    private void showAge(){
        System.out.print("(私有)年龄:");
    }
    protected void showScore(){
        System.out.print("(保护)分数:");
    }

    public String printName(String name){
        System.out.print("(公共string)name:"+name);
        return name;
    }
    private double printScore(double score){
        System.out.print("(私有double)score:"+score);
        return score;
    }
    protected int printAge(int age){
        System.out.print("(保护age)age:"+age);
        return age;
    }

}
private static void methodTest() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> methodSC = Class.forName("com.reflection.MethodStudent");
        Method[] declaredMethods = methodSC.getDeclaredMethods();
        for (Method m : declaredMethods){
            System.out.print("ReflectTest 获取所有的方法:"+m+"\n");
        }
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Method[] methods = methodSC.getMethods();
        for (Method m : methods){
            System.out.print("ReflectTest获取所有的公有方法"+m+"\n");
        }
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Method score = methodSC.getDeclaredMethod("printScore", double.class);
        Object o = methodSC.getConstructor().newInstance();
        score.setAccessible(true);
        Object invoke = score.invoke(o, 9.8);
        System.out.print("ReflectTest调用制定的私有方法:"+invoke+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");

        Method printName = methodSC.getMethod("printName", String.class);
        Object maoge = printName.invoke(o, "Maoge");
        System.out.print("ReflectTest公有有参数方法:"+maoge+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Method showName = methodSC.getMethod("showName", null);
        System.out.print("ReflectTest公有无参方法:"+showName+"\n");
        System.out.print("ReflectTest----------分割线-------------"+"\n");
        Method printAge = methodSC.getDeclaredMethod("printAge", int.class);
        printAge.setAccessible(true);
        Object invoke1 = printAge.invoke(o, 20);
        System.out.print("ReflectTest受保护的方法:"+invoke1);
    }

这是反射的一些基础使用

下面说一下动态代理 (代理可以让我们的方法或者类进行功能扩展 解耦等好处)

新建一个接口

public interface Person {
    void work();
}

新建一个接口实现类(被角色代理)

public class PersonImpl implements Person{

    @Override
    public void work() {
        System.out.print("i am PersonImpl.calss");

    }
}

新建一个代理角色

public class PersonHandler implements InvocationHandler {
    public Object px;

    public PersonHandler(Object px) {
        this.px = px;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.print("do work"+"\n");
        return method.invoke(px,args);
    }
}

绑定代理

public class PersonProxyTest {
    public static void main(String[] args) {
        Person person = new PersonImpl();
        Person  o = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class[]{Person.class}, new PersonHandler(person));
        o.work();
    }

}

好了 本文到此结束 欢迎留言或私信

猜你喜欢

转载自blog.csdn.net/naide_s/article/details/81083845
今日推荐