美文网首页
java的反射机制

java的反射机制

作者: 名字_都被占了 | 来源:发表于2018-05-11 20:54 被阅读0次

    每当我们编写并且编译一个新创建的类java虚拟机就会产生一个对应的Class对象,并且这个Class对象会被保存在同名.class文件里。当我们new一个新对象或者引用静态成员变量时,java虚拟机中的类加载器就会将对应的Class对象加载到java虚拟机中,然后java虚拟机再根据这个Class对象的相关信息创建我们需要的实例对象或提供静态变量的引用值。需要特别注意的是,每个class类,无论创建多少个实例对象,在JVM中都对应同一个Class对象。

    几种能够获取Class对象的方法

    1:Object.getClass(),通过对象实例获取对应Class对象,注意对于基本类型无法使用该方法获取Class对象。
    2:通过类的类型获取Class对象,基本类型也可以使用这种方法,比如Class c=boolean.class;
    3:Class.forName(),通过类的全限定名获取Class对象,基本类型无法使用该方法获取Class对象,比如Class c=Class.forName("java.lang.String");
    4:Class.getSuperclass(),获得给定类的父类Class

    使用总结:

    1:只要是获取private修饰的构造方法(Constructor),成员变量(Field),成员方法(Method)的时候,调用的方法中都会包含Declared这个词,public修饰的就不用调用该方法。
    2:只要是调用private修饰的构造方法,成员变量,成员方法,都要使用setAccessible方法来跳过权限检查。

    示例一:成员变量public,构造方法private的情况下,给new一个实例

    public class CeShi {
        public static void main(String[] args) {
            Class student=Student.class;
            try {
                Constructor<Student> constructor=student.getDeclaredConstructor(String.class,int.class,String.class);
                constructor.setAccessible(true);
                try {
                    Student student1= constructor.newInstance("laoliang",24,"taiyuan");
                    System.out.println(student1.toString());
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }
    class Student{
        public String name;
        public int age;
        public String address;
        private Student(String name,int age,String adderss){
            this.name=name;
            this.age=age;
            this.address=adderss;
        }
    
        @Override
        public String toString() {
            return "名字为"+name+"年龄为"+age+"地址为"+address;
        }
    }
    

    示例二:成员变量private,构造方法public的情况下,给成员变量赋值

    public class CeShi {
        public static void main(String[] args) {
            Class student=Student.class;
            try {
                Constructor<Student> constructor=student.getDeclaredConstructor(String.class,int.class,String.class);
                try {
                    Student student1= constructor.newInstance("laofu",22,"xiaoyi");
                    Field name=student.getDeclaredField("name");
                    name.setAccessible(true);
                    name.set(student1,"laoliang");
                    Field age=student.getDeclaredField("age");
                    age.setAccessible(true);
                    age.setInt(student1,24);
                    Field address=student.getDeclaredField("address");
                    address.setAccessible(true);
                    address.set(student1,"taiyuan");
                    System.out.println(student1.toString());
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }
    class Student{
        private String name;
        private int age;
        private String address;
        public Student(String name,int age,String adderss){
            this.name=name;
            this.age=age;
            this.address=adderss;
        }
    
        @Override
        public String toString() {
            return "名字为"+name+"年龄为"+age+"地址为"+address;
        }
    }
    

    示例三:通过反射来访问private修饰的成员方法

    public class CeShi {
        public static void main(String[] args) {
            Class student=Student.class;
            try {
                Constructor<Student> constructor=student.getDeclaredConstructor(String.class,int.class,String.class);
                try {
                    Student student1= constructor.newInstance("laoliang",24,"taiyuan");
                    Method method=student.getDeclaredMethod("getMethod",String.class);
                    method.setAccessible(true);
                    String s= (String) method.invoke(student1,"你好啊");
                    System.out.println(s);
                } catch (InstantiationException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
    }
    class Student{
        private String name;
        private int age;
        private String address;
        public Student(String name,int age,String adderss){
            this.name=name;
            this.age=age;
            this.address=adderss;
        }
    
        @Override
        public String toString() {
            return "名字为"+name+"年龄为"+age+"地址为"+address;
        }
        private String getMethod(String canShu){
            return "我是私有方法,你输入的参数是"+canShu+",并且你的"+toString();
        }
    

    参考文章
    www.jianshu.com/p/607ff4e79a13

    相关文章

      网友评论

          本文标题:java的反射机制

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