天天看點

Java第四課 - Java反射的學習(一)Java第四課 - Java反射的學習(一)

Java第四課 - Java反射的學習(一)

定義

先來看下百度百科的定義。

JAVA反射機制是在運作狀态中,對于任意一個實體類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動态擷取資訊以及動态調用對象方法的功能稱為Java語言的反射機制。

翻譯一下,就是通過反射機制,來擷取類的名稱,方法,修飾符等等。

這麼說可能會有點抽象,我們來舉個栗子。

舉個栗子

定義SysUser類

這個是一個基礎的系統使用者的類,用來描述系統使用者的賬号、密碼。

注意,這裡的userName,我定義為了public類型。

public class SysUser {
    private int userId;
    public String userName;
    private String password;
    public void sayHello(){
        System.out.println("hello");
    }
}
           

定義main方法

由于是示範,這裡就直接放在main方法,友善示範。

定義對象,擷取Class

SysUser sysUser = new SysUser();
Class<? extends SysUser> sysUserClass = sysUser.getClass();
           

得到sysUserClass這個對象之後,可以做什麼呢?我們進入一下Class這個類去看看。

Java第四課 - Java反射的學習(一)Java第四課 - Java反射的學習(一)

可以看到,有許許多多的方法,我們挑選幾個來說明一下。

擷取對象的名稱,包含整個包名。

String sysUserClassName = sysUserClass.getName();
System.out.println(sysUserClassName);
           

列印結果為

com.mowie.javastudy.javaclass.SysUser

接着,我們來試着列印一下字段,即屬性。

Field[] fields = sysUserClass.getFields();
for (Field field : fields) {
    System.out.println(field.getName());
}

           

列印結果為

userName

可以看到,結果是一個數組我們是定義了三個字段,但是這裡隻顯示了一個。說明,getFields()方法隻會顯示public修飾的字段。

接着,我們再來列印一下方法。

Method[] methods = sysUserClass.getMethods();
for (Method method : methods) {
    System.out.println(method.getName());
}
           

列印結果為

main

sayHello

wait

wait

wait

equals

toString

hashCode

是以也可以看到getMethods()方法,同時也會把超級父類Object的方法也給列印出來的。

main方法的代碼如下。

public static void main(String[] args) {
    
    SysUser sysUser = new SysUser();
    Class<? extends SysUser> sysUserClass = sysUser.getClass();
    String sysUserClassName = sysUserClass.getName();
    System.out.println(sysUserClassName);
    Field[] fields = sysUserClass.getFields();
    for (Field field : fields) {
        System.out.println(field.getName());
    }
    Method[] methods = sysUserClass.getMethods();
    for (Method method : methods) {
        System.out.println(method.getName());
    }
}
           

通過類名建立對象

我們換個思路,平時我們建立對象,都是通過new關鍵詞。

如果我們現在已經知道了包名以及類名,是否可以通過反射來建立對象呢?答案是肯定的。

舉個栗子

同樣的,我們也直接在main方法裡面進行示範就好了。

首先,是把包名以及類型定義好。接着,通過Class.forName()方法,把Class對象給建立出來。

Class有了之後,再通過newInstance()方法,進行執行個體化對象。

我們也可以看到,這裡執行個體化出來的對象,是一個Object類型的對象。是以我們需要進行強制轉換。

強制轉換後,我們調用SysUser的方法sayHello。可以看到,列印出來的結果就是:hello。

這就說明了,我們的對象建立成功啦!

public static void main(String[] args) {
    String className = "com.mowie.javastudy.javaclass.SysUser";
    try {
        Class<?> aClass = Class.forName(className);
        Object o = aClass.newInstance();
        SysUser sysUser = (SysUser) o;
        sysUser.sayHello();
    }catch (Exception e){
        e.printStackTrace();
    }
}
           

總結

通過反射,其實是可以做到很多很靈活的操作的,例如在代碼中擷取對象名、對象方法等等。

具體看操作場景,我們這裡也就先熟悉一下,以後要運用的時候,知道有反射這個東西就可以了。