天天看點

Java反射——反射擷取類的結構資訊——第四章1:通過反射擷取類的結構資訊5:反射爆破建立執行個體

Java反射——反射機制問題——第一章

Java反射——Class類——第二章

Java反射——類加載——第三章

Java反射——反射擷取類的結構資訊——第四章

文章目錄

  • 1:通過反射擷取類的結構資訊
    • 1.1 java.lang.Class類
    • 1.2 java.lang.reflect.Field類
    • 1.3 java.lang.reflect.Method類
    • 1.4 java.lang.reflect.Constructor類
  • 5:反射爆破建立執行個體

1:通過反射擷取類的結構資訊

1.1 java.lang.Class類

  1. getName:擷取全類名
  2. getSimpleName:擷取簡單類名
  3. getFields:擷取所有public修飾的屬性,包含本類以及父類的
  4. getDeclaredFields:擷取本類中所有屬性
  5. getMethods:擷取所有public修飾的方法,包含本類以及父類的
  6. getDeclaredMethods:擷取本類中所有方法
  7. getConstructors:擷取所有public修飾的構造器,包含本類
  8. getDeclaredConstructors:擷取本類中所有構造器
  9. getPackage:以Package形式傳回包資訊
  10. getSuperClass:以Class形式傳回父類資訊
  11. getInterfaces:以Class[]形式傳回接口資訊
  12. getAnnotations:以Annotation形式傳回注解資訊

對如上12個點,進行代碼示範

public class ReflectiionUtils {
    public static void main(String[] args) {
    }
    @Test
    //第一組方法api
    public  void api_01() throws Exception {
        //擷取class對象
        Class<?> personcls = Class.forName("com.reflection.Person");
        Object o = personcls.newInstance();
//        1. getName:擷取全類名
        System.out.println("全類名:"+personcls.getName());
//        2. getSimpleName:擷取簡單類名
        System.out.println("簡單類名:"+personcls.getSimpleName());
//        3. getFields:擷取所有public修飾的屬性,包含本類以及父類的
        Field[] fields = personcls.getFields();
        for (Field fields1:fields){
            System.out.println("擷取所有public修飾的屬性"+fields1.getName());
        }
//        4. getDeclaredFields:擷取本類中所有屬性
        Field[] fieldss = personcls.getDeclaredFields();
        for (Field fields1:fieldss){
            System.out.println("擷取本類中所有屬性"+fields1.getName());
        }
//        5. getMethods:擷取所有public修飾的方法,包含本類以及父類的
        Method[] methods = personcls.getMethods();
        for (Method methods1:methods){
            System.out.println("擷取所有public修飾的方法,包含本類以及父類的"+methods1.getName());

        }
// 6. getDeclaredMethods:擷取本類中所有方法
//        7. getConstructors:擷取所有public修飾的構造器,包含本類以及父類的
        Constructor<?>[] constructors = personcls.getConstructors();
        for (Constructor constructor:constructors){
            System.out.println("取所有public修飾的構造器,包含本類以及父類的:"+constructor);
        }
// 8. getDeclaredConstructors:擷取本類中所有構造器

//        9. getPackage:以Package形式傳回包資訊
        System.out.println("以Package形式傳回包資訊:"+personcls.getPackage());
//        10. getSuperClass:以Class形式傳回父類資訊
        System.out.println("以Class形式傳回父類資訊:"+personcls.getSuperclass());
//        11. getInterfaces:以Class[]形式傳回接口資訊
        System.out.println("以Class[]形式傳回接口資訊:"+personcls.getInterfaces());
//        12. getAnnotations:以Annotation形式傳回注解資訊
    }
}
class A{
    public String names;
    public void m4(){}
    private void m5(){}
}
interface B{

}
class Person extends  A implements B{
    //屬性
    public String name;
    protected int age;
    String job;
    private double sal;
    //方法
    public void m1(){}
    public void m2(){}
    public void m3(){}
    public Person(){
    }
}
           

1.2 java.lang.reflect.Field類

  1. getModifiers:以int形式傳回修飾符

[說明:預設修飾符是0,public 是1 , private是2 , protected是4,static是8 , final 是16], public(1) + static (8) = 9

  1. getType:以Class形式傳回類型
  2. getName:傳回屬性名

    對如上3個點,進行代碼示範

@Test
    //第二組方法api  java.lang.reflect.Field類
    public  void api_02() throws Exception {
        //擷取class對象
        //1.以int形式傳回修飾符
        Class<?> personcls = Class.forName("com.reflection.Person");
        Field[] fields = personcls.getDeclaredFields();
        for (Field field:fields){
            System.out.println("本類中所有屬性:"+field.getName()+",以int形式傳回修飾符:"+field.getModifiers()+",以Class形式傳回類型:"+field.getType());
        }
    }
    class Person {
    //屬性
    public String name;
    protected int age;
    String job;
    private double sal;
}
           
本類中所有屬性:name,以int形式傳回修飾符:1,以Class形式傳回類型:class java.lang.String
本類中所有屬性:age,以int形式傳回修飾符:4,以Class形式傳回類型:int
本類中所有屬性:job,以int形式傳回修飾符:0,以Class形式傳回類型:class java.lang.String
本類中所有屬性:sal,以int形式傳回修飾符:2,以Class形式傳回類型:double
           

1.3 java.lang.reflect.Method類

  1. getModifiers:以int形式傳回修飾符

[說明:預設修飾符是0 , public 是1,private是2 , protected是4,static是8,final 是16]

  1. getReturnType:以Class形式擷取傳回類型
  2. getName:傳回方法名
  3. getParameterTypes:以Class[]傳回參數類型數組

對如上4個點,進行代碼示範

@Test
    //第三組方法api  java.lang.reflect.Field類
    public  void api_03() throws Exception {
        //擷取class對象
        //1.以int形式傳回修飾符
        Class<?> personcls = Class.forName("com.reflection.Person");
        Method[] methods = personcls.getDeclaredMethods();
        for (Method method:methods){
            System.out.println("本類中所有方法名:"+method.getName()+",以int形式傳回修飾符:"+method.getModifiers()+",以Class形式擷取傳回類型:"+method.getReturnType());
            Class<?>[] parameterType = method.getParameterTypes();
            for (Class<?> parameterTypes:parameterType ){
                System.out.println("以Class[]傳回參數類型數組:"+parameterTypes);
            }
        }
    }
           
class Person {
    //方法
    public void m1(int m1,float m2){}
    public void m2(){}
    public void m3(){}
}
           
本類中所有方法名:m1,以int形式傳回修飾符:1,以Class形式擷取傳回類型:void
以Class[]傳回參數類型數組:int
以Class[]傳回參數類型數組:float
本類中所有方法名:m2,以int形式傳回修飾符:1,以Class形式擷取傳回類型:void
本類中所有方法名:m3,以int形式傳回修飾符:1,以Class形式擷取傳回類型:void
           

1.4 java.lang.reflect.Constructor類

  1. getModifiers:以in形式傳回修飾符
  2. getName:傳回構造器名(全類名)
  3. getParameterTypes:以Class[]傳回參數類型數組

對如上3個點,進行代碼示範

@Test
    //第四組方法api  java.lang.reflect.Constructor類
    public  void api_04() throws Exception {
        //擷取Constructor對象
        //1.以int形式傳回修飾符
        Class<?> personcls = Class.forName("com.reflection.Person");
        Constructor[] methods = personcls.getDeclaredConstructors();
        for (Constructor method:methods){
            System.out.println("本類中所有構造器名:"+method.getName()+",以int形式傳回修飾符:"+method.getModifiers());
            Class<?>[] parameterType = method.getParameterTypes();
            for (Class<?> parameterTypes:parameterType ){
                System.out.println("以Class[]傳回參數類型數組:"+parameterTypes);
            }
        }
    }
    class Person{
//構造器
    public Person(int m1,float m2){
    }
    public Person(double m1,char m2){
    }
}
           
本類中所有構造器名:com.reflection.Person,以int形式傳回修飾符:1
以Class[]傳回參數類型數組:double
以Class[]傳回參數類型數組:char
本類中所有構造器名:com.reflection.Person,以int形式傳回修飾符:1
以Class[]傳回參數類型數組:int
以Class[]傳回參數類型數組:float
           

5:反射爆破建立執行個體

通過反射建立對象

  1. 方式一: 調用類中的public修飾的無參構造器
  2. 方式二:調用類中的指定構造器
  3. Class類相關方法

newlnstance :調用類中的無參構造器,擷取對應類的對象

getConstructor(Class…clazz):根據參數清單,擷取對應的public構造器對象getDecalaredConstructor(Class…clazz):根據參數清單,擷取對應的構造器對象

  1. Constructor類相關方法

setAccessible:暴破(暴力破解,使用反射可以通路private構造器/方法/屬性,反射面前都是紙老虎)

newlnstance(Object…obj):調用構造器

測試1:通過反射建立某類的對象,要求該類中必須有public的無參構造

測試2:通過調用某個特定構造器的方式,實作建立某類的對象

public class ReflectCreateInstance {
    public static void main(String[] args) throws Exception {
        //1.調用類中的public修飾的無參構造器
        Class<?> cls = Class.forName("com.reflection.Persons");
        Object o = cls.newInstance();
        System.out.println(o);
        //2.通過public的有參構造器建立執行個體
        Constructor<?> constructor = cls.getConstructor(int.class, String.class);
        Object zzz = constructor.newInstance(20, "zzz");
        System.out.println(zzz);
        //3.通過非public的有參構造器建立執行個體
        Constructor<?> constructors = cls.getDeclaredConstructor(int.class);
        constructors.setAccessible(true);
        Object z = constructors.newInstance(60);
        System.out.println(z);
    }
}
class Persons{
    private int age=10;
    private String name="zlj";
    public Persons(){

    }
    public Persons(int age,String name){
        this.age=age;
        this.name=name;
    }
    private Persons(int age){
        this.age=age;
        this.name=name;
    }
    @Override
    public String toString() {
        return "Persons{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
           
Persons{age=10, name='zlj'}
Persons{age=20, name='zzz'}
Persons{age=60, name='zlj'}