zoukankan      html  css  js  c++  java
  • 27.反射2.md


    目录

    1.反射

    定义:把一个字节码文件加载到内存中,jvm对该字节码文件解析,创造一个Class对象,把字节码文件中的信息全部存储到Class对象中,使用这个Class对象调用其属性和方法

    2.类对象获取

    package per.liyue.code.relfect;
    public class ReflectMain {
        public static void main(String[] args) throws Exception {
            /*
             * 类的获取
             */
            
            //加载类方式一:forName
            Class class1 = Class.forName("per.liyue.code.relfect.Person");
            System.out.println("forName加载:" + class1);
            
            //加载类方式二:
            Class class2 = Person.class;
            System.out.println(".class方式获取:" + class2);
            System.out.println("class1 == class2 ?" + (class1==class2));
            
            //加载类方式三:
            Person person = new Person();
            Class class3 = person.getClass();
            System.out.println("getClass方式获取:" + class3);
            System.out.println("class1 == class3 ?" + (class1==class3));
            
        }
    }
    

    3.构造函数获取

    注意公有和私有构造获取区别:

    • 私有构造可获取私有构造
    • 私有构造获取类自身的构造
    package per.liyue.code.reflect;
    public class Person {
        private String name = null;
        private int id = 0;
        
        public Person(){
            
        }
        
        public Person(String name){
            this.name = name;
        }
        
        private Person(String name, int id){
            this.name = name;
            this.id = id;
        }
        
        //公有函数
        public void FunPublic(int num){
            System.out.println("这个公有函数的输入值是:" + Integer.toString(num));
        }
        
        //私有函数
        public void FunPrivate(String concent){
            System.out.println("这个私有函数的输入内容是:" + concent);
        }
        
    
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "成功构造一个Person对象:name为:" + this.name + "id为:" + this.id;
        }
    }
    
    package per.liyue.code.reflect;
    import java.lang.reflect.Constructor;
    public class ReflectGetConstructor {
        public static void main(String[] args) throws Exception {
            //获取类对象
            Class clazz = Class.forName("per.liyue.code.reflect.Person");
                    
            //1.公有构造
            //1.1获取所有公有构造
            Constructor[] constructors =  clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
            
            //1.2获取指定构造
            Constructor c = clazz.getConstructor(String.class);
            System.out.println(c);
            
            //1.3使用公有构造产生一个对象
            Person p = (Person) clazz.newInstance();
            System.out.println(p);
                    
            //2.私有构造:注意这里会将类私有和公有构造都获取到
            Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
            for (Constructor constructor : declaredConstructors) {
                System.out.println(constructor);
            }
            
            //2.1指定私有构造获取
            Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class);
            System.out.println(declaredConstructor);
            
            
            //2.2使用私有构造产生一个对象
            //这里直接使用创建对象将报错,因为权限访问限制导致
            //Person dP = (Person) declaredConstructor.newInstance("张三", 1);
            /*
             * 暴力反射
             * 这里先将权限打开,后面即可使用私有构造,但是这样的情况下,单例模式是失效的,不过现实中不会这么用!
             */
            declaredConstructor.setAccessible(true);
            Person dP = (Person) declaredConstructor.newInstance("张三", 1);        
        }
    }
    

    4.函数获取

    package per.liyue.code.reflect;
    public class Person {
        private String name = null;
        private int id = 0;
        
        public Person(){
            
        }
        
        public Person(String name){
            this.name = name;
        }
        
        private Person(String name, int id){
            this.name = name;
            this.id = id;
        }
        
        //公有函数
        public void FunPublic(int num){
            System.out.println("这个公有函数的输入值是:" + Integer.toString(num));
        }
        
        //私有函数
        private void FunPrivate(String concent){
            System.out.println("这个私有函数的输入内容是:" + concent);
        }
        
        //静态函数
        public static void FunStatic(int id){
            System.out.println("这个静态函数的输入内容是:" + Integer.toString(id));
        }
        
        //参数是数组
        public void FunArray(int []    array){
            System.out.println("这个函数输入数组长度为:" + array.length);
        }
        
        //无参函数
        public void FunVoid(){
            System.out.println("这个函数没有入参");
        }
        
        @Override
        public String toString() {
            // TODO Auto-generated method stub
            return "成功构造一个Person对象:name为:" + this.name + "id为:" + this.id;
        }
    }
    
    package per.liyue.code.reflect;
    import java.lang.reflect.Method;
    public class ReflectGetMethod {
        public static void main(String[] args) throws Exception {
            //获取类对象
            Class clazz = Class.forName("per.liyue.code.reflect.Person");
            Person p = (Person)clazz.newInstance();
            
            //1.获取公有函数
            Method[] m = clazz.getMethods();
            for(Method method : m){
                System.out.println(method);
            }
                    
            //1.1获取指定公有函数
            Method mGet = clazz.getMethod("FunPublic", int.class);
            //这里需要对象
            mGet.invoke(p, 1);
            
            //2.获取私有函数
            Method[] mP = clazz.getDeclaredMethods();
            for(Method mp : mP){
                System.out.println(mp);
            }
            
            //2.1获取指定私有函数
            Method mm = clazz.getDeclaredMethod("FunPrivate", String.class);
            //这里需要将权限打开才能正确调用
            mm.setAccessible(true);
            mm.invoke(p, "哈哈");
            //这里需要对象
            //mGet.invoke(p, 1);
            
            //3.获取数组函数,入参为数组比较特别,需要注意
            Method mA = clazz.getDeclaredMethod("FunArray", int[].class);
            mA.invoke(p, new int[]{});
            
            //4.获取静态函数:今天函数不需要类对象
            Method mS = clazz.getDeclaredMethod("FunStatic", int.class);
            mS.invoke(null, 123);
            
        }
    }
    

    4.注解反射

  • 相关阅读:
    MRO C3算法 super的运用
    约束 抛异常
    反射
    Ubuntu
    Vim
    Vim
    Arithmetic
    Docker-常用命令
    Docker
    Docker-LAMP开发环境
  • 原文地址:https://www.cnblogs.com/bugstar/p/8492847.html
Copyright © 2011-2022 走看看