首頁 > Java > java教程 > 主體

Java反射取得類別和物件資訊的詳細介紹

黄舟
發布: 2017-03-28 10:51:53
原創
1577 人瀏覽過

反射可以解決在編譯時無法預知物件和類別是屬於那個類別的,要根據程式執行時間的資訊才能知道該物件和類別的資訊的問題。

在兩個人協作開發時,你只要知道對方的類別名稱就可以進行初步的開發了。

取得類別物件

  • Class.forName(String clazzName)靜態方法

  • 呼叫類別的class屬性,Person. class回傳的就是Person的class物件(建議使用)

  • 呼叫某個物件的getClass()方法

具體使用還是要根據實際來選擇,第一種方式是比較自由的,只要知道一個類別名稱就可以了,其不會做該類別是否存在的校驗,第二種、第三種則會做校驗

取得類別的資訊

取得類別建構器

  • Connstructor<T> getConstructor(Class<?>.. .parameterTypes):傳回此Class物件對應類別的帶有指定形參的public建構器

  • Constructor<?>[] getConstructors() :傳回此Class物件對應類別的所有public建構子

  • Constructor<T>[] getDeclaredConstructor(Class<?>...parameterTypes):傳回此class物件對應類別的帶指定參數的建構器,與建構器的存取權限無關

  • #Constructor<?>[] getDeclaredConstructors():傳回此class物件對應類別的所有建構器,與建構器的存取權限無關

取得類別成員方法

  • Method getMethod (String name,Class<?>...parameterTypes):傳回此class物件對應類別的帶有指定形參的public方法

  • ##Method[] getMethods():傳回此class物件所表示的類別的所有public方法

  • Method getDeclaredMethod(string name,Class...parameterTypes) :傳回此class物件對應類別的帶指定形參的方法,與方法存取權限無關

  • #Method[] getDeclaredMethods():傳回此class物件對應類別的全部方法,與方法的存取權限無關

取得類別成員變數

  • Field getField(String name ):傳回此class物件對應類別的指定名稱的public成員變數

  • #Field[] getFields():傳回此class物件對應類別的所有public成員變數

  • Field getDeclaredField(String name):傳回此class物件對應類別的指定名稱的成員變量,與成員變數存取權限無關

  • Field[] getDeclaredFields():傳回此class物件對應類別的全部成員變量,與成員變數的存取權限無關

#取得類別註解

取得該類別內部類別

  • Class<?>[] getDeclaredClasses():傳回該class隊形對應類別裡所包含的全部內部類別

取得該類別物件所在的外部類別

  • # Class<?> getDeclaringClass():傳回該Class物件對應類別所在的外部類別

取得該類別物件對應類別所實作的介面

  • #Class<?>[] getInterfaces():傳回該Class物件對應類別所實作的全部介面

取得該類別物件對應類別所繼承的父類別

  • #Class<? super T> getSuperclass():傳回該Class物件對應類別的超類別的Class物件

取得該類別物件對應類別的修飾符、所在套件、類別名稱等基本資訊

判斷該類別是否為介面、枚舉、註解類型

  • boolean isAnnotation():傳回此class物件是否表示一個註解類型

  • #boolean isAnnotationPresent(Class<?extends Annotation>annotationClass):判斷此Class物件是否使用類別Annotation修飾

  • <a href="http://www.php.cn/wiki/60.html" target="_blank"></a>

  • boolean isAnonymousClass()
:傳回此class物件是否是一個

匿名類別

    boolean isArray()
  • :傳回此class對象是否表示一個

    陣列類別

  • boolean isEnum():傳回此class物件是否表示一個枚舉

  • #boolean isInterface():傳回此class物件是否表示一個介面

  • boolean isInstance(Object

  • #obj )
  • :判斷obj是否是此class物件的實例,該方法可以完全取代instanceof

    運算元

  • public interface Colorable {
         public void value();
    }
    登入後複製
    public class ClassInfo {
    
        public static void main(String[] args) throws NoSuchMethodException, SecurityException {
            Class<Colorable> cls=Colorable.class;
            System.out.println(cls.getMethod("value"));
            System.out.println(cls.isAnnotation());
            System.out.println(cls.isInterface());
        }
    
    }
    登入後複製
#
public abstract void com.em.Colorable.value()
false
true
登入後複製

Java8中新增的方法參數反射

int getParameterCount()

:取得該建構器或方法的形參數

Parameter[] getParameters():取得該建構器或方法的所有形參

#########getModifiers( )###:取得修飾該形參的修飾符###############String getName()###:取得形參名########## #####Type getParameterizedType()###:取得泛型的形參類型###############ClassgetType()###:取得形參考類型###############boolean isNamePresent()###:此方法傳回該類別的class檔案中是否包含了方法的形參名資訊######## ########boolean isVarArgs()###:此方法用來判斷該參數是否為個數可變的形參#########
public class Test {
    public void getInfo(String str,List<String>list){
        System.out.println("成功");
    }
}
登入後複製
public class ClassInfo {

    public static void main(String[] args) throws NoSuchMethodException, SecurityException {
        Class<Test> cls=Test.class;
        Method med=cls.getMethod("getInfo", String.class,List.class);
        System.out.println(med.getParameterCount());
        Parameter[] params=med.getParameters();
        System.out.println(params.length);
        for(Parameter par:params){
            System.out.println(par.getName());
            System.out.println(par.getType());
            System.out.println(par.getParameterizedType());
        }
    }

}
登入後複製
######結果# #####
2
2
arg0
class java.lang.String
class java.lang.String
arg1
interface java.util.List
java.util.List<java.lang.String>
登入後複製
###反射產生物件############使用Class物件的newInstance()方法建立Class物件的實例,該方法要求要有預設建構器(比較常用) ############先使用Class物件取得指定的Constructor對象,在呼叫Constructor物件的newInstance()方法來建立該Class物件對應類別的實例########## ##反射呼叫方法###############Object invoke(Object obj,Object...args)###:該方法中的obj是執行該方法的主調,後面的args是執行此方法時傳入此方法的實參#########
public class Test {

    public Test(String str) {
        System.out.println(str);
    }
    public void getInfo(String str){
        System.out.println(str);
    }
}
登入後複製
public class ClassInfo {

    public static void main(String[] args) throws Exception {
        Class<Test> cls=Test.class;
        Constructor<Test>construct=cls.getConstructor(String.class);
        Test test=construct.newInstance("初始化");
        Method med=cls.getMethod("getInfo", String.class);
        med.invoke(test, "调用方法成功");
    }

}
登入後複製
######結果######
初始化
调用方法成功
登入後複製
登入後複製
###接下來看官仔細看下面的栗子###
public class Test {

    public Test(String str) {
        System.out.println(str);
    }
    //私有方法
    private void getInfo(String str){
        System.out.println(str);
    }
}
登入後複製
public class ClassInfo {

    public static void main(String[] args) throws Exception {
        Class<Test> cls=Test.class;
        Constructor<Test>construct=cls.getConstructor(String.class);
        Test test=construct.newInstance("初始化");
      //为啥使用这个方法呢?
        Method med=cls.getDeclaredMethod("getInfo", String.class);
      //为啥使用这个方法呢?
        med.setAccessible(true);
        med.invoke(test, "调用方法成功");
    }

}
登入後複製
######結果######
初始化
调用方法成功
登入後複製
登入後複製
######setAccessible(boolean flag):將值設為true,指示該Method在使用是應該取消Java語言的存取權限檢查#########存取成員變數值###############getXxx(Object obj)###:取得obj物件的該成員變數的值。此處的Xxx對應8種基本類型,如果該成員變數的型別是###引用###類型的,則去掉Xxx部分###############setXxx(Object obj ,Xxx val)###:將obj物件的該成員變數設定為val值。此處的Xxx對應8中基本類型,如果該成員變數的類型是引用類型,則取消set後面的Xxx###############以上兩個方法可以方法所有的成員變量,包括private的私有成員變數######
public class Test {
    private int num;

    public Test(String str) {
        System.out.println(str);
    }
    private void getInfo(String str){
        System.out.println(str);
    }
    public int getNum() {
        return num;
    }
    public void setNum(int num) {
        this.num = num;
    }

}
登入後複製
public class ClassInfo {

    public static void main(String[] args) throws Exception {
        Class<Test> cls=Test.class;
        Constructor<Test>construct=cls.getConstructor(String.class);
        Test test=construct.newInstance("初始化");
        Method med=cls.getDeclaredMethod("getInfo", String.class);
        med.setAccessible(true);
        med.invoke(test, "调用方法成功");
        Field fld=cls.getDeclaredField("num");
        fld.setAccessible(true);
        fld.setInt(test, 12);
        System.out.println(fld.getInt(test));
    }

}
登入後複製
######結果######
初始化
调用方法成功
12
登入後複製
###操作數組######java.lang.reflect套件下有一個Array類,其可以動態建立數組#########static Object newInstance(ClasscomponentType,int...length)###:建立一個具有指定的元素類型、指定維度的新數組###

static xxx getXxx(Object array,int index):返回array数组中第index个元素。其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变为get()

static void setXxx(Object array,int index,xxx val):将array数组中低index 个元素的值设为val,其中xxx是各种基本数据类型,如果数组元素是引用类型,则该方法变为set()

public class ArrayInfo {

    public static void main(String[] args) {
        Object arrays=Array.newInstance(String.class, 3);
        Array.set(arrays, 0, "第一个");
        Array.set(arrays, 1, "第二个");
        Array.set(arrays, 2, "第三个");
        System.out.println(Array.get(arrays, 2));
    }
}
登入後複製

以上是Java反射取得類別和物件資訊的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!