反射


一、概念

  1.反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法。

  2.反射可以在一个类运行的时候获取类的信息的机制,可以获取在编译期不可能获得的类的信息。

  3.对于任意一个对象,都能调用它的任意一个方法和属性(private:落魄了,家人们)。

  4.因为类的信息是保存在Class对象中的,而这个Class对象是在程序运行时被类加载器(ClassLoader)动态加载的。

  5.当类加载器装载运行了类后,动态获取Class对象的信息以及动态操作Class对象的属性和方法的功能称为Java语音的反射机制。

二、作用

  1.反编译:.class —> .java。

  2.通过反射机制访问Java对象中的属性、方法、构造方法等。

三、原理

  利用加载到jvm中的.class文件来进行操作,.class文件中包含java类的所有信息,当你不知道某个类具体信息时,可以使用反射获取class,然后进行各种操作。

  在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。

  总结说:反射就是把java类中的各种成分映射成一个个的Java对象,并且可以进行操作。

四、获取class的三种方法

            List<Class> classList=new ArrayList<Class>();
            //获取class的三种方式
            //1.通过对象调用getClass()方法获取
            classList.add(human.getClass());
            //2.通过类名.class获取(ps:所有类都有一个隐含的静态的成员变量class)。首选方法,安全可靠性能高
            classList.add(Human.class);

            //3.通过CLass类的静态方法forName()获取,注意该方法可能抛出ClassNotFound异常
            classList.add(Class.forName("reflex.Human"));

            System.out.println(classList.toString());

 

五、Class类的主要方法

  getName():获得类的完整名字。

  getFields():获得类的public类型的属性。

  getDeclaredFields():获得类的所有属性。包括private 声明的和继承类

  getMethods():获得类的public类型的方法。

  getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类

  getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。

  getConstructors():获得类的public类型的构造方法。

  getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

  newInstance():通过类的构造方法创建这个类的一个对象。

六、实例

public class Human {
    public String name;
    private int age=18;
    public static String text="---static text---";

    public int getAge() {
        return age;
    }

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

    void human(){
    }

    private void fly(){
        System.out.println("can not fly");
    }

    public void hello(){
        System.out.println("hello");
    }

}
public class ReflexTest {
    public static void main(String[] args) {
        System.out.println(Human.text);
        Human human=new Human();
        try {
            List<Class> classList=new ArrayList<Class>();
            //获取class的三种方式
            //1.通过对象调用getClass()方法获取
            classList.add(human.getClass());
            //2.通过类名.class获取(ps:所有类都有一个隐含的静态的成员变量class)。首选方法,安全可靠性能高
            classList.add(Human.class);

            //3.通过CLass类的静态方法forName()获取,注意该方法可能抛出ClassNotFound异常
            classList.add(Class.forName("reflex.Human"));

            System.out.println(classList.toString());

            System.out.println(classList.get(1).getName());

            System.out.println("private:落魄了,家人们");
            Field field=classList.get(1).getDeclaredField("age");
            System.out.println(field);
            System.out.println(human.getAge());
            //设置可访问private
            field.setAccessible(true);

            //设置private变量的值
            field.set(human,100);
            System.out.println(human.getAge());

            Method privateMethod =classList.get(1).getDeclaredMethod("fly",null);
            privateMethod.setAccessible(true);
            privateMethod.invoke(human,null);

            System.out.println("------getFields:");
            //getFields()获取public类型的成员变量
            Field[] fieldsOfPublic=classList.get(1).getFields();
            for (Field i:fieldsOfPublic) {
                System.out.println(i);
            }
            System.out.println("------getDeclaredFields:");
            //getDeclaredFields()获取所有成员变量
            Field[] fieldsAll = classList.get(1).getDeclaredFields();
            for (Field j:fieldsAll) {
                System.out.println(j);
            }

            //getMethod(name,paramterTypes)只能获取public类型的成员方法
            Method method=classList.get(1).getMethod("hello",null);
            System.out.println("获取成员方法hello--"+method);

            //getDeclaredMethods()获取所有成员方法
            Method[] methods=classList.get(1).getDeclaredMethods();
            System.out.println("所有成员方法");
            for (Method m:methods) {
                System.out.println(m);
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}

 参考:

  https://blog.csdn.net/qq_24549805/article/details/104013083

  https://blog.csdn.net/huangliniqng/article/details/88554510


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM