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.注解反射

原文地址:https://www.cnblogs.com/bugstar/p/8492847.html