反射的学习总结

2020-08-04  本文已影响0人  132xin

反射的定义

Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任何一个对象,都能够调用它的任意方法和属性。这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。在使用反射机制中第一步是获取该类的字节码文件,然后可以获取该类的信息。

获取字节码文件的三种方式

根据类名 :类名.class
根据对象:对象.getClass
根据全限定类名:Class.forName(全限定类名)

//根据类名
        Class class1=Person.class;
        //更据对象
        Person person=new Person("Reflex", 18);
        Class class2=person.getClass();
        //根据全限定名
        try {
            Class class3 = Class.forName("Reflex.Person");
        } catch (ClassNotFoundException e) {
            
            e.printStackTrace();
        }

反射的优缺点:

优点:

反射提高了Java程序的灵活性和扩展性,降低耦合性,提高自适应能力。

缺点:

性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。
使用反射会模糊程序内部逻辑:程序员希望在源代码中看到程序的逻辑,反射等绕过了 源代码的技术,因而会带来维护问题。反射代码对比相应的直接代码要复杂。

获取信息

获取构造方法
/**
    /**
     * 获取构造参数
     * 
     * @param class1
     */
    public static Person getConstructor(Class class1) {

        try {
            //获取构造参数,传入的参数决定获取哪个构造方法
            Constructor constructor=class1.getConstructor(String.class,int.class);
            //进行实例化
            Object preson=constructor.newInstance("Reflex",18);
            preson.toString();
            return (Person) preson;
        } catch (Exception e) {

            e.printStackTrace();
        }
        return null;
    }
    /**
     * 获取所有的参数
     */
    public static void getConstructors(Class class1) {
        Constructor[] constructors=class1.getConstructors();
        for(int i=0;i<constructors.length;i++) {
            //获取每个构造函数中的参数类型的字节码对象
            Class[] parameterTypes=constructors[i].getParameterTypes();
            System.out.println("第"+i+"构造参数");
            for(int j=0;j<parameterTypes.length;j++) {
                System.out.print(parameterTypes[j].getName()+",");
            }
        }
    }
    
获取属性
//获取属性
     public static void getField(Class class1) {
         try {
             Person person=getConstructor(class1);
             //获取成员变量,通过指定name来获取
              Field publicField=class1.getField("age");
             //获取私有的成员变量
             Field declaredFiled=class1.getDeclaredField("name");
             //对私有的属性进行操作时,要打开权限
             declaredFiled.setAccessible(true);
             //复杂等操作
             declaredFiled.set(person, "ReflexField");
             publicField.set(person, 19);
             person.toString();
            
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
         //获取全部属性的方法
         Field[] fields=class1.getFields();
         //获取所有的私有属性
         Field[] fields2=class1.getDeclaredFields();
        
     }
    
获取方法

    // 获取方法
    public static void getMethod(Class class1) {
         try {
             Person person=getConstructor(class1);
             /**
              *  classs.getMethod(name,paraMeterTypes)
              * name:方法的名称
              * paraMeterTypes:方法的参数类型,没有则什么都不填 例如:String.class 
             */
             Method eatMethod=class1.getMethod("eat", String.class);
             //获取私有的方法
            // Method privateMethod=class1.getDeclaredMethod(name, parameterTypes)
             //打开权限,私有的方法一定要加上打开权限
             eatMethod.setAccessible(true);
             //调用方法
             /*
             * method.invoke(obj,args)
             * obj:方法的对象
             * args:实际的参数值,没有则不填
             */
             eatMethod.invoke(person, "猪肉");
             
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
         //获取所有的方法
         Method[] methods=class1.getMethods();
         //所有私有的方法
         Method[] privateMethods=class1.getDeclaredMethods();
         
     }

所有的代码:

public class ReflexTest {

    public static void main(String[] args) {
        // 根据类名
        Class class1 = Person.class;
        // 更据对象
        Person person = new Person("Reflex", 18);
        Class class2 = person.getClass();
        // 根据全限定名
        try {
            Class class3 = Class.forName("Reflex.Person");
        } catch (Exception e) {

            e.printStackTrace();
        }
        getConstructor(class1);
        getConstructors(class1);
        getField(class1);
        getMethod(class1);

    }

    /**
     * 获取构造参数
     * 
     * @param class1
     */
    public static Person getConstructor(Class class1) {

        try {
            // 获取构造参数,传入的参数决定获取哪个构造方法
            Constructor constructor = class1.getConstructor(String.class, int.class);
            // 进行实例化
            Object preson = constructor.newInstance("Reflex", 18);
            preson.toString();
            return (Person) preson;
        } catch (Exception e) {

            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取所有的参数
     */
    public static void getConstructors(Class class1) {
        Constructor[] constructors = class1.getConstructors();
        for (int i = 0; i < constructors.length; i++) {
            // 获取每个构造函数中的参数类型的字节码对象
            Class[] parameterTypes = constructors[i].getParameterTypes();
            System.out.println("第" + i + "构造参数");
            for (int j = 0; j < parameterTypes.length; j++) {
                System.out.print(parameterTypes[j].getName() + ",");
            }
        }
    }

    // 获取属性
    public static void getField(Class class1) {
        try {
            Person person = getConstructor(class1);
            // 获取成员变量,通过指定name来获取
            Field publicField = class1.getField("age");
            // 获取私有的成员变量
            Field declaredFiled = class1.getDeclaredField("name");
            // 对私有的属性进行操作时,要打开权限
            declaredFiled.setAccessible(true);
            // 复杂等操作
            declaredFiled.set(person, "ReflexField");
            publicField.set(person, 19);
            person.toString();

        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        // 获取全部属性的方法
        Field[] fields = class1.getFields();
        // 获取所有的私有属性
        Field[] fields2 = class1.getDeclaredFields();

    }

    // 获取方法
    public static void getMethod(Class class1) {
         try {
             Person person=getConstructor(class1);
             /**
              *  classs.getMethod(name,paraMeterTypes)
              * name:方法的名称
              * paraMeterTypes:方法的参数类型,没有则什么都不填 例如:String.class 
             */
             Method eatMethod=class1.getMethod("eat", String.class);
             //获取私有的方法
            // Method privateMethod=class1.getDeclaredMethod(name, parameterTypes)
             //打开权限,私有的方法一定要加上打开权限
             eatMethod.setAccessible(true);
             //调用方法
             /*
             * method.invoke(obj,args)
             * obj:方法的对象
             * args:实际的参数值,没有则不填
             */
             eatMethod.invoke(person, "猪肉");
             
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
         //获取所有的方法
         Method[] methods=class1.getMethods();
         //所有私有的方法
         Method[] privateMethods=class1.getDeclaredMethods();
         
     }

}

class Person {
    private String name;
    public int age;

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

    public Person(String name) {
        this.name = name;
    }

    public Person() {

    }

    public void eat(String food) {
        System.out.println("正在吃" + food);
    }
    @Override
    public String toString() {
        String string = "Person " + name + " " + age;
        System.out.println(string);
        return string;
    }

}
上一篇 下一篇

猜你喜欢

热点阅读