1. 程式人生 > >Java反射之——Java獲取類中成員變數和建構函式的資訊

Java反射之——Java獲取類中成員變數和建構函式的資訊

我們無論是獲取成員變數資訊,亦或者是獲取建構函式的資訊,都必須獲取類的類型別,然後通過類的類型別進行對成員變數和建構函式的操作。

注:成員變數和建構函式也都是物件,前者是Feild的物件,在java.lang.reflec.Feild中封裝了對成員變數的資訊。後者是Constructor的物件,在java.lang.reflec.Constructor中封裝了對建構函式的資訊。

一、獲取類中成員變數的資訊

getDeclaredFields()——獲取的是自身宣告的成員變數,無修飾符的限制;

getFields()獲取的是public修飾的成員變數

我們推薦使用getDeclaredFields()

getType()——獲取成員變數的型別的類型別

奉上程式碼:

/**
 * 獲取類中成員變數的資訊
 * 注:成員變數也是物件,是Field類的物件,在java.lang.reflec.Field包中封裝了對成員變數的操作
 *
 */
public class FieldUtil {
    public static void print(Object obj) {
        //獲取類的類型別
        Class c = obj.getClass();
        System.out.println("類的全稱:"+c.getName());
        //獲取類中的成員變數
        //注:推薦使用getDeclaredFields(),因為該方法獲取的是類自身宣告的全部成員變數,沒有修飾許可權的限制
        //而getFields()獲取的是public修飾的成員變數
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            //獲取成員變數的型別的類型別
            Class fieldType = field.getType();
            System.out.print("成員變數的型別的名稱:"+fieldType.getName()+" ");
            //獲取成員變數的全稱
            System.out.println("成員變數的名稱:"+field.getName());
        }
    }
}

在主函式中呼叫:FieldUtil.print("hello");

輸出結果:

類的全稱:java.lang.String
成員變數的型別的名稱:[C 成員變數的名稱:value
成員變數的型別的名稱:int 成員變數的名稱:hash
成員變數的型別的名稱:long 成員變數的名稱:serialVersionUID
成員變數的型別的名稱:[Ljava.io.ObjectStreamField; 成員變數的名稱:serialPersistentFields
成員變數的型別的名稱:java.util.Comparator 成員變數的名稱:CASE_INSENSITIVE_ORDER

在主函式中呼叫:FieldUtil.print(new Integer(1));

輸出結果:

類的全稱:java.lang.Integer
成員變數的型別的名稱:int 成員變數的名稱:MIN_VALUE
成員變數的型別的名稱:int 成員變數的名稱:MAX_VALUE
成員變數的型別的名稱:java.lang.Class 成員變數的名稱:TYPE
成員變數的型別的名稱:[C 成員變數的名稱:digits
成員變數的型別的名稱:[C 成員變數的名稱:DigitTens
成員變數的型別的名稱:[C 成員變數的名稱:DigitOnes
成員變數的型別的名稱:[I 成員變數的名稱:sizeTable
成員變數的型別的名稱:int 成員變數的名稱:value
成員變數的型別的名稱:int 成員變數的名稱:SIZE
成員變數的型別的名稱:int 成員變數的名稱:BYTES
成員變數的型別的名稱:long 成員變數的名稱:serialVersionUID

二、獲取建構函式的資訊(建構函式無返回值)

getDeclaredConstructors()——獲取的是自身宣告的建構函式,沒有修飾符的限制,建構函式必須是自身宣告的

getConstructors()——獲取的是所有public型別的建構函式

getParameterTypes()——獲取的是引數列表的型別的類型別

程式碼奉上:

/**
 * 獲取類中建構函式的資訊
 * 建構函式也是物件,是Constructor的物件,在java.lang.reflec.Constructor包中封裝了對建構函式的操作
 *
 */
public class ConstructorUtil {

    public static void print(Object obj) {
        //獲取類的類型別
        Class c = obj.getClass();
        System.out.println("類的全稱:"+c.getName());
        //獲取類中的建構函式
        //注:推薦使用getDeclaredConstructors(),獲取的是自身宣告的建構函式,沒有修飾符的限制,建構函式必須是自身宣告的
        //getConstructors()獲取的是所有public型別的建構函式
        Constructor[] ct = c.getDeclaredConstructors();
        for (Constructor constructor : ct) {
            //建構函式無返回值型別
            //獲取建構函式的名稱
            String constructorName = constructor.getName();
            System.out.print("建構函式的名稱:"+constructorName+"(");
            //獲取建構函式引數列表的型別的類型別
            Class[] paramTypes = constructor.getParameterTypes();
            for (Class class1 : paramTypes) {
                System.out.print("引數列表的名稱是:"+class1.getName()+",");
            }
            System.out.println(")");
        }
        
        
    }
}

主函式呼叫:ConstructorUtil.print("hello");

輸出結果:

類的全稱:java.lang.String
建構函式的名稱:java.lang.String(引數列表的名稱是:[B,引數列表的名稱是:int,引數列表的名稱是:int,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[B,引數列表的名稱是:java.nio.charset.Charset,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[B,引數列表的名稱是:java.lang.String,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[B,引數列表的名稱是:int,引數列表的名稱是:int,引數列表的名稱是:java.nio.charset.Charset,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[B,引數列表的名稱是:int,引數列表的名稱是:int,引數列表的名稱是:java.lang.String,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[C,引數列表的名稱是:boolean,)
建構函式的名稱:java.lang.String(引數列表的名稱是:java.lang.StringBuilder,)
建構函式的名稱:java.lang.String(引數列表的名稱是:java.lang.StringBuffer,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[B,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[I,引數列表的名稱是:int,引數列表的名稱是:int,)
建構函式的名稱:java.lang.String()
建構函式的名稱:java.lang.String(引數列表的名稱是:[C,)
建構函式的名稱:java.lang.String(引數列表的名稱是:java.lang.String,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[C,引數列表的名稱是:int,引數列表的名稱是:int,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[B,引數列表的名稱是:int,)
建構函式的名稱:java.lang.String(引數列表的名稱是:[B,引數列表的名稱是:int,引數列表的名稱是:int,引數列表的名稱是:int,)