1. 程式人生 > >Java反射獲取類和物件資訊全解析

Java反射獲取類和物件資訊全解析

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

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

獲取類物件

  • 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物件對應類的全部成員變數,與成員變數的訪問許可權無關
獲取類註解
  • <A extends Annotation>A getAnnotation(Class<A>annotationClass):嘗試獲取該class物件對應類上村子的指定型別的Annotation,如果該型別註解不存在,則返回null
  • <A extends Annotation>A getDeclaredAnnotation(Class<A>annotationClass):這是Java 8中新增的,該方法獲取直接修飾該class物件對應類的指定型別的Annotation,如果不存在,則返回null
  • Annotation[] getAnnotations():返回修飾該class物件對應類上存在的所有Annotation
  • Annotation[] getDeclaredAnnotations():返回修飾該Class物件對應類上存在的所有Annotation
  • <A extends Annotation>A[] getAnnotationByType(Class<A>annotationClass):該方法的功能與前面介紹的getAnnotation()方法基本相似,但由於Java8增加了重複註解功能,因此需要使用該方法獲取修飾該類的指定型別的多個Annotation
  • <A extends Annotation>A[] getDeclaredAnnotationByType(Class<A>annotationClass):該方法發功能與前面介紹的getDeclaredAnnotations()方法相似,也是因為Java8的重複註解的功能,需要使用該方法獲取直接修飾該類的指定型別的多個Annotation
獲取該類內部類
  • Class<?>[] getDeclaredClasses():返回該class隊形對應類裡包含的全部內部類
獲取該類物件所在的外部類
  • Class<?> getDeclaringClass():返回該Class物件對應類所在的外部類
獲取該類物件對應類所實現的介面
  • Class<?>[] getInterfaces():返回該Class物件對應類所實現的全部介面
獲取該類物件對應類所繼承的父類
  • Class<? super T> getSuperclass():返回該Class物件對應類的超類的Class物件
獲取該類物件對應類的修飾符、所在包、類名等基本資訊
  • int getModifiers():返回此類或介面的所有修飾符,修飾符由public、protected、private、final、static、abstract等對應的常量組成,返回的整數應使用Modifier工具類的方法來解碼,才可以獲取真是的修飾符
  • Package getPackage():獲取該類的包
  • String getName():以字串形式返回此CLass物件所表示的類的簡稱
判斷該類是否為介面、列舉、註解型別
  • boolean isAnnotation():返回此class物件是否表示一個註解型別
  • boolean isAnnotationPresent(Class<? extends Annotation>annotationClass):判斷此Class物件是否使用類Annotation修飾
  • 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():獲取帶泛型的形參型別
  • Class<?>getType():獲取形參型別
  • 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(Class<?>componentType,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));
    }
}

更多內容可以關注微信公眾號,或者訪問AppZone網站

http://7xp64w.com1.z0.glb.clouddn.com/qrcode_for_gh_3e33976a25c9_258.jpg

相關推薦

手寫spring二:Java反射獲取物件資訊解析

反射在這裡的作用就是知道全路徑 在框架啟動的時候把類例項化 然後設定到@service 和@Autowired裡面 所以要了解這東西怎麼用的 1. 什麼是類物件 類物件,就是用於描述這種類,都有什麼屬性,什麼方法的 2. 獲取類物件 獲取類物件有3種方式 (1). Class.f

Java反射獲取物件資訊解析

反射可以解決在編譯時無法預知物件和類是屬於那個類的,要根據程式執行時的資訊才能知道該物件和類的資訊的問題。 在兩個人協作開發時,你只要知道對方的類名就可以進行初步的開發了。 獲取類物件 Class.forName(String clazzName)靜

Class物件 java反射 AccessibleObject 註解

java 反射機制:在程式中獲取已載入到jvm中的java物件的資訊,並檢測或修改 獲取構造器 獲取成員變數 獲取方法 明顯 Accessible並不是標識方法能否訪問的. public的方法 Accessible仍為false  使用了method.setAccess

java中的物件

類 類在客觀世界裡是不存在的,是描寫物件的資訊 類是模子,確定物件將會擁有的特徵(屬性)和行為(方法)  類的特點 類是物件的型別 具有相同屬性和方法的一組物件的集合 屬性(特徵) int cpu  = 5.5; int screen 

java基礎篇---------物件(OOP)

JAVA 的是完全面向物件程式設計的!!! 面向物件程式設計的三大特性:封裝、繼承、多型 1.類 類是構造物件的模板或者藍圖,由類構造物件的過程就是建立類的例項; 類裡面存放類的成員變數,成員方法, class student { private int age; //

JAVA程式設計基礎——物件(繼承、多型)

一、單利模式 (1)單例類只能有一個例項; (2)單例類必須自己建立自己的唯一例項; (3)單例類必須給所有其他物件提供這個例項。 場景:一個類可以定義無數個物件,但是隻有一個例項。 1、餓漢式單利模式 package practise.test1030; //餓漢式單利模式

Java筆記:物件

Java類和物件 類是在程式設計中經過編寫的,擁有成員變數和一些方法的一種資料型別,可以由自己通過聯絡現實中的事物進行編寫,關鍵字是class,一個Java原始檔只能含有一個public類,且該類名稱與檔名相同。類是對現實中具體事物的一種表示,並且需藉由類建立

java認證筆記-------物件(1)

類和物件思維導圖 類和物件的關係: 類是實體特徵的集合,是對物件的抽象,是一種抽象的資料型別。              物件是一種具體的事物是一個具體的概念。 可以說類是個體抽象的集合,物件是具體具體事物的呈現。例如人類是一個類,小明是一個具有人類特徵的物件。

java 反射獲取的靜態屬性值

public class AppTest {    private NodeClass nodeClass;    public static String  hehe = "hehe";    public

Java反射獲取getset方法

反射bean的get方法 /** * java反射bean的get方法 * * @param objectClass * @param fieldName * @return */

Java學習筆記——物件

類 類是一組相關屬性和行為的集合,可以看作是一類事物的模板 屬性:該事物的資訊狀態 行為:就是該事物能做什麼 例子:狗 屬性:名字,體重,年齡,顏色 行為:走,跑,叫 Java中用class描述事物也似如此: 成員變數:對應事物的屬性 成員方法:對應事物的行為 通常情況下,一個類並不能直

Java 7:物件(域、引數、初始化)

面向物件程式設計:每個物件包含對使用者公開的特定功能部分和隱藏的實現部分,在OOP中不必關心物件的具體實現,OOP更看重資料(結構),而不是具體演算法。 封裝(資料隱藏):將資料和行為組合在一個包裡,並對物件的使用者隱藏資料的實現方式,封裝的關鍵是絕不能讓其他類直接訪問例項

php反射獲取方法中的註釋

通過php中的反射機制,獲取該類的文件註釋,再通過獲取其所有的方法,獲取方法的註釋 所用到的主要類及其方法 ReflectionClass ReflectionClass::getDocComment ReflectionClass::getMethods $meth

java反射——獲取一個Object物件內的一切!

有些時候你明明知道這個object裡面是什麼,但是因為種種原因,你不能將它轉化成一個物件,只是想單純地提取出這個object裡的一些東西,這個時候就需要用反射了。 假如你這個類是這樣的: private class User { String userName;

java 反射獲取中所有的屬性(含父

直接上程式碼 public static List<Field> getFieldList(Class<?> clazz){ if(null == clazz){

關於初學者如何理解面向物件和麵向過程的區別以及java中的物件

首先java是一門面向物件的程式語言,特別是當你剛入門C語言的同時又進行java語言的學習,這個問題就體現出來了。C語言是面向過程的程式語言,它們兩種語言處理問題的方式是不一樣的。 面向過程的程式語言的設計思路按步驟走的,你需要手把手的教它。例如上課鈴響了,學

java利用反射獲取資訊

在java.lang.reflect包中有三個類Field、Monthod和Constructor分別描述類的域、方法和構造器。還可以使用java.lang.reflect包中的Modifier類的靜態方法分析getModifiers返回的整型數值。例如可以使用ispubl

java反射工具--通過指定屬性名,獲取/設定物件屬性值

java物件通過點運算子操作物件屬性的方式沒法使用for,while等迴圈,此工具主要解決這一問題. 例如:有一物件包含屬性有一定規律 obj1: { name1: "張三", age1: 1, name2: "李四", age2: 2

Java 反射建立的例項物件(預設構造方法私有構造方法)

反射之建立類的例項物件 通過反射可以建立Class<?>中”?”對應的型別的例項物件,眾所眾知,建立類物件,會呼叫構造方法,構造器可以有多個,預設構造方法,多引數構造方法等。 這裡演示,通過反射建立預設構造方法的例項物件,和帶引數的構造方法的例項

Java反射專題學習-獲取的構造資訊

今天繼續學習反射專題之獲取類的建構函式資訊: 繼上篇部落格來寫:我們單獨寫一個方法來獲取類的建構函式資訊:(通過獲取Constructor) 列印類的建構函式相關資訊 public static void ConMessage(Object object) {