Java 反射

作者: 久伴我还是酒伴我 | 来源:发表于2020-05-22 13:37 被阅读0次

    简介

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

    当JVM把class加载到内存的时候,会同步的产生关于这个文件的Class对象,这个对象里面封装的就是类的信息,而且,不管我们new 使用多少次,我们的JVM只会为它创建一个Class对象。

    我们反射的本质就是得到Class对象之后,通过调用Class中的方法反向的获取Person对象的各种信息

    获取Class对象

    反射的关键是要获取到对象,然后调用Class对象里面的信息来达到我们的目的,比如类的路径,方法,变量等等,下面介绍下获取Class对象的几种方式

    第一种

      /**
         * 获取Class对象
         * @param args
         */
        public static void main(String[] args) {
            Demo demo=new Demo();
            Class demoClass = demo.getClass();
            System.out.println("get class first info"+demoClass);
        }
    

    比如传递过来Object,可通过该方式获取对象

    第二种

       /**
         * 获取Class对象
         * @param args
         */
        public static void main(String[] args) {
            Class demoClass = Demo.class;
            System.out.println("get class second info"+demoClass);
        }
    

    程序性能更高,安全可靠

    第三种

     /**
         * 获取Class对象
         * @param args
         */
        public static void main(String[] args) {
            try{
                Class demoClass = Class.forName("com.glj.webservice.demo.Demo");
                System.out.println("获取到的对象:" + demoClass);
            } catch (Exception e){
                e.printStackTrace();
            }
        }
    

    forName() 静态方法来获取,用的最多

    反射-获取成员变量

    package com.glj.webservice.demo.reflex;
    
    import java.io.Serializable;
    
    public class ReflexClass implements Serializable {
        public String name;
    
        private int age;
    
        String address;
    
        protected String count;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getCount() {
            return count;
        }
    
        public void setCount(String count) {
            this.count = count;
        }
    
        @Override
        public String toString() {
            return "ReflexClass{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", address='" + address + '\'' +
                    ", count='" + count + '\'' +
                    '}';
        }
    }
    
    
    package com.glj.webservice.demo.reflex;
    
    import java.lang.reflect.Field;
    import java.util.Arrays;
    
    public class ReflexTest {
        /**
         * 获取Class对象
         * @param args
         */
        public static void main(String[] args) throws Exception {
            // 获取Class 对象 可通过上述三种方式任何一种即可
            Class perClass = ReflexClass.class;
    
            System.out.println("获取所有字段");
            Field[] fields = perClass.getDeclaredFields();
            Arrays.stream(fields).forEach(v -> System.out.println(v));
    
            System.out.println("获取所有的public 字段");
            fields = perClass.getFields();
            Arrays.stream(fields).forEach(v -> System.out.println(v));
    
            System.out.println("根据名字获取指定字段");
            Field f = perClass.getDeclaredField("address");
            System.out.println(f);
    
            // 将Class 对象进行初始化
            Object ob = perClass.getConstructor().newInstance();
            f.set(ob,"北京市朝阳区望京Soho 塔1");
            ReflexClass re = (ReflexClass)ob;
            System.out.println("获取设定的值"+re.getAddress());
        }
    }
    
    

    打印结果:
    获取所有字段
    public java.lang.String com.glj.webservice.demo.reflex.ReflexClass.name
    private int com.glj.webservice.demo.reflex.ReflexClass.age
    java.lang.String com.glj.webservice.demo.reflex.ReflexClass.address
    protected java.lang.String com.glj.webservice.demo.reflex.ReflexClass.count
    获取所有的public 字段
    public java.lang.String com.glj.webservice.demo.reflex.ReflexClass.name
    根据名字获取指定字段
    java.lang.String com.glj.webservice.demo.reflex.ReflexClass.address
    获取设定的值北京市朝阳区望京Soho 塔1

    反射-获取构造函数并调用

    package com.glj.webservice.demo.reflex;
    
    import java.io.Serializable;
    
    public class ReflexClass implements Serializable {
        /**
         * public
         */
        public String name;
        /**
         * 默认
         */
        String address;
        /**
         * 受保护的
         */
        protected String count;
        /**
         * 私有的
         */
        private int age;
    
        /**
         * 无参构造
         */
        public ReflexClass() {
            System.out.println("调用了公有、无参构造方法");
        }
    
        /**
         * public 字段构造
         * @param name
         */
        public ReflexClass(String name) {
            this.name = name;
            System.out.println("公共字段一个参数构造 name:" + name);
        }
    
        /**
         * 多个字段构造
         * @param name
         * @param address
         */
        public ReflexClass(String name, String address) {
            this.name = name;
            this.address = address;
            System.out.println("name:"+name+"address:"+ address);
        }
    
        /**
         * protected 构造
         * @param age
         */
        protected  ReflexClass(int age) {
            this.age = age;
            System.out.println("受保护的构造方法age = " + age);
        }
    
        /**
         * 私有的构造
         * @param bls
         */
        private  ReflexClass(boolean bls) {
            System.out.println("受保护的构造方法bls = " + bls);
        }
    
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getCount() {
            return count;
        }
    
        public void setCount(String count) {
            this.count = count;
        }
    
        @Override
        public String toString() {
            return "ReflexClass{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", address='" + address + '\'' +
                    ", count='" + count + '\'' +
                    '}';
        }
    }
    
    package com.glj.webservice.demo.reflex;
    
    import java.lang.reflect.Constructor;
    import java.lang.reflect.Field;
    import java.util.Arrays;
    
    public class ReflexTest {
        /**
         * 获取Class对象
         * @param args
         */
        public static void main(String[] args) throws Exception {
    
            Class demoClass = Class.forName("com.glj.webservice.demo.reflex.ReflexClass");
    
            System.out.println("获取所有的公有构造");
            Constructor[] constructors = demoClass.getConstructors();
            Arrays.stream(constructors).forEach(v -> System.out.println(v));
    
            System.out.println("所有的构造方法(包括:私有、受保护、默认、公有)");
            constructors = demoClass.getDeclaredConstructors();
            Arrays.stream(constructors).forEach(v -> System.out.println(v));
    
            System.out.println("获取公有的无参构造");
            Constructor constructor = demoClass.getConstructor();
            System.out.println(constructor);
    
            System.out.println("根据类型获取构造");
            constructor = demoClass.getDeclaredConstructor(boolean.class);
            System.out.println(constructor);
    
            // 暴力访问(忽略掉修饰符)
           constructor.setAccessible(true);
           constructor.newInstance(Boolean.FALSE);
    
        }
    }
    
    

    输出结果
    获取所有的公有构造
    public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String,java.lang.String)
    public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String)
    public com.glj.webservice.demo.reflex.ReflexClass()
    所有的构造方法(包括:私有、受保护、默认、公有)
    private com.glj.webservice.demo.reflex.ReflexClass(boolean)
    protected com.glj.webservice.demo.reflex.ReflexClass(int)
    public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String,java.lang.String)
    public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String)
    public com.glj.webservice.demo.reflex.ReflexClass()
    获取公有的无参构造
    public com.glj.webservice.demo.reflex.ReflexClass()
    根据类型获取构造
    private com.glj.webservice.demo.reflex.ReflexClass(boolean)
    私有构造方法bls = false

    反射-获取方法并调用

    package com.glj.webservice.demo.reflex;
    
    import java.io.Serializable;
    
    public class ReflexClass implements Serializable {
       public void getName(){
           System.out.println("调用了共有的无参方法getName");
       }
        private void getName(String name){
            System.out.println("调用了共有的无参方法getName:"+name);
        }
        protected void getAge(int age){
            System.out.println("调用了共有的无参方法getAge:"+age);
        }
        void run(){
            System.out.println("调用了:默认的,无参的run()");
        }
        private String study(int age){
            System.out.println("调用了,私有的,并且有返回值的,int参数的study(): age = " + age);
            return "abcd";
        }
    
        public String getAll(int age,String name){
            System.out.println("调用了公共的并且有返回值的age"+age+"name"+name);
           return "age"+age+"name"+name;
        }
    }
    
    
    package com.glj.webservice.demo.reflex;
    
    
    import java.lang.reflect.Method;
    import java.util.Arrays;
    
    public class ReflexTest {
        /**
         * 获取Class对象
         * @param args
         */
        public static void main(String[] args) throws Exception {
    
            Class demoClass = Class.forName("com.glj.webservice.demo.reflex.ReflexClass");
    
            System.out.println("获取所有的方法(私有、公有、受保护、默认)");
            Method[] methods = demoClass.getDeclaredMethods();
            Arrays.stream(methods).forEach(v -> System.out.println(v));
    
            System.out.println("获取所有公有的方法");
            methods = demoClass.getMethods();
            Arrays.stream(methods).forEach(v -> System.out.println(v));
    
            System.out.println("根据方法名称获取的方法有参");
            Method method = demoClass.getDeclaredMethod("getName",String.class);
            System.out.println(method);
    
            Object ob = demoClass.getConstructor().newInstance();
            method.setAccessible(true);
            //  两个参数 一个是参数值 一个是参数类型
            method.invoke(ob,"刘德华");
    
        }
    }
    
    

    输出结果
    获取所有的方法(私有、公有、受保护、默认)
    void com.glj.webservice.demo.reflex.ReflexClass.run()
    public void com.glj.webservice.demo.reflex.ReflexClass.getName()
    private void com.glj.webservice.demo.reflex.ReflexClass.getName(java.lang.String)
    private java.lang.String com.glj.webservice.demo.reflex.ReflexClass.study(int)
    protected void com.glj.webservice.demo.reflex.ReflexClass.getAge(int)
    获取所有公有的方法
    public void com.glj.webservice.demo.reflex.ReflexClass.getName()
    public boolean java.lang.Object.equals(java.lang.Object)
    public java.lang.String java.lang.Object.toString()
    public native int java.lang.Object.hashCode()
    public final native java.lang.Class java.lang.Object.getClass()
    public final native void java.lang.Object.notify()
    public final native void java.lang.Object.notifyAll()
    根据方法名称获取的方法有参
    private void com.glj.webservice.demo.reflex.ReflexClass.getName(java.lang.String)
    调用了共有的无参方法getName:刘德华

    总结

    Java 反射很多,只介绍到常用的获取变量 获取构造获取方法,这几个目前够用了,后续再慢慢补充

    相关文章

      网友评论

        本文标题:Java 反射

        本文链接:https://www.haomeiwen.com/subject/edkxahtx.html