首頁 > Java > Java入門 > 主體

java裡什麼是反射

青灯夜游
發布: 2023-01-13 00:40:09
原創
18447 人瀏覽過

在java中,反射主要是指程式可以存取、偵測和修改它本身狀態或行為的一種能力。 Java反射機制的主要功能:1、在執行時期判斷任意一個物件所屬的類別;2、在執行時建構任意一個類別的物件;3、在執行時期呼叫任意一個物件的方法等。

java裡什麼是反射

本教學操作環境:windows7系統、java8版、DELL G3電腦。

什麼是反射(Reflection )?

主要是指程式可以存取、偵測和修改它本身狀態或行為的一種能力

Java反射?

在Java執行環境中,對於任意一個類,能否知道這個類別有哪些屬性和方法?對於任意一個對象,能否呼叫它的任意一個方法

Java反射機制主要提供了以下功能:

 * 1.在執行時判斷任意一個物件所屬的類別。

 * 2.在運行時建構任一個類別的物件。

 * 3.在執行時判斷任一個類別所具有的成員變數和方法。

 * 4.在執行時呼叫任一個物件的方法。 

Reflectio

Reflection是Java被視為動態(或準動態)語言的關鍵性質。

這個機制允許程式在運行時透過Reflection APIs取得任何一個已知名稱的class的內部資訊。

包括其modifiers(諸如public、static等)、 superclass(例如Object)、實現了的interfaces (例如Serializable)、也包括其fields和methods的所有信息,並可於運行時改變fields內容或調用methods。

動態語言

  動態語言的定義「程式執行時,允許改變程式結構或變數類型,這種語言稱為動態語言」。

  從這個觀點看,Perl,Python,Ruby是動態語言,C ,Java,C#不是動態語言。

  儘管在這樣的定義與分類下Java不是動態語言,它卻有著非常突出的動態相關機制:Reflection。這個字的意思是:反射、映像、倒影,用在Java身上指的是我們可以於執行時間載入、探知、使用編譯期間完全未知的classes。

  換句話說,Java程式可以載入一個執行時才得知名稱的class,得知其完整建構(但不包括methods定義),並產生其物件實體、或對其fields設值、或喚起其methods。

  這種「看透」class的能力(the ability of the program to examine itself)稱為introspection(內省、內觀、反省)。 Reflection和introspection是常被並提的兩個術語。

Java Reflection API簡介

  在JDK中,主要由以下類別來實作Java反射機制,這些類別(除了第一個)都位於java.lang. reflect套件中

  Class類:代表一個類,位於java.lang套件下。

  Field類別:代表類別的成員變數(成員變數也稱為類別的屬性)。

  Method類別:代表類別的方法。

  Constructor類別:代表類別的建構方法。

  Array類別:提供了動態建立數組,以及存取陣列的元素的靜態方法。

Class物件

要想使用反射,首先需要取得待操作的類別所對應的Class物件。

Java中,無論產生某個類別的多少個對象,這些物件都會對應到同一個Class物件。

這個Class物件是由JVM產生的,透過它能夠獲悉整個類別的結構。

常用的取得Class物件的3種方式:

1.使用Class類別的靜態方法。例如:  

Class.forName(“java.lang.String”);
登入後複製

2.使用類別的.class語法。如:

String.class;
登入後複製

3.使用物件的getClass()方法。如:

String str = “aa”; 
Class
登入後複製

例程1:取得方法

例程DumpMethods類別示範了Reflection API的基本作用,它讀取命令列參數指定的類別名,然後列印這個類別所具有的方法資訊。 

import java.lang.reflect.Method;
 
public class DumpMethods
{
    public static void main(String[] args) throws Exception //在方法后加上这句,异常就消失了
    {
        //获得字符串所标识的类的class对象
        Class<?> classType = Class.forName("java.lang.String");//在此处传入字符串指定类名,所以参数获取可以是一个运行期的行为,可以用args[0]
 
        //返回class对象所对应的类或接口中,所声明的所有方法的数组(包括私有方法)
        Method[] methods = classType.getDeclaredMethods();
 
        //遍历输出所有方法声明
        for(Method method : methods)
        {
            System.out.println(method);
        }
    }
 
}
登入後複製

例程2:透過反射呼叫方法 

透過反射呼叫方法。詳情請見程式碼及註解:

import java.lang.reflect.Method;
 
public class InvokeTester
{
    public int add(int param1, int param2)
    {
        return param1 + param2;
 
    }
 
    public String echo(String message)
    {
        return "Hello: " + message;
    }
 
    public static void main(String[] args) throws Exception
    {
 
        // 以前的常规执行手段
        InvokeTester tester = new InvokeTester();
        System.out.println(tester.add(1, 2));
        System.out.println(tester.echo("Tom"));
        System.out.println("---------------------------");
 
        // 通过反射的方式
 
        // 第一步,获取Class对象
        // 前面用的方法是:Class.forName()方法获取
        // 这里用第二种方法,类名.class
        Class<?> classType = InvokeTester.class;
 
        // 生成新的对象:用newInstance()方法
        Object invokeTester = classType.newInstance();
        System.out.println(invokeTester instanceof InvokeTester); // 输出true
 
        // 通过反射调用方法
        // 首先需要获得与该方法对应的Method对象
        Method addMethod = classType.getMethod("add", new Class[] { int.class,
                int.class });
        // 第一个参数是方法名,第二个参数是这个方法所需要的参数的Class对象的数组
 
        // 调用目标方法
        Object result = addMethod.invoke(invokeTester, new Object[] { 1, 2 });
        System.out.println(result); // 此时result是Integer类型
 
        //调用第二个方法
        Method echoMethod = classType.getDeclaredMethod("echo", new Class[]{String.class});
        Object result2 = echoMethod.invoke(invokeTester, new Object[]{"Tom"});
        System.out.println(result2);
 
    }
}
登入後複製

產生物件

若想透過類別的不帶參數的建構方法來產生對象,我們有兩種方式:

1.先取得Class對象,再透過該Class物件的newInstance()方法直接產生即可:

 Class<?> classType = String.class;
 
 Object obj = classType.newInstance();
登入後複製

2.先取得Class對象,再透過該物件取得對應的Constructor對象,再透過該Constructor物件的newInstance()方法產生

(其中Customer是一個自訂的類,有一個無參數的建構方法,也有參數的建構方法):

    Class<?> classType = Customer.class;
 
    // 获得Constructor对象,此处获取第一个无参数的构造方法的
    Constructor cons = classType.getConstructor(new Class[] {});
 
    // 通过构造方法来生成一个对象
    Object obj = cons.newInstance(new Object[] {});
登入後複製

若想透過類別的帶參數的構造方法產生對象,只能使用下面這一種方式:

(Customer為一個自訂的類,有無參數的構造方法,也有一個帶參數的構造方法,傳入字串和整數)

    Class<?> classType = Customer.class;
 
    Constructor cons2 = classType.getConstructor(new Class[] {String.class, int.class});
 
    Object obj2 = cons2.newInstance(new Object[] {"ZhangSan",20});
登入後複製

可以看出调用构造方法生成对象的方法和调用一般方法的类似,不同的是从Class对象获取Constructor对象时不需要指定名字,而获取Method对象时需要指定名字。

相关视频教程推荐:Java视频教程

以上是java裡什麼是反射的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板