1. 程式人生 > >java反射詳解---反射的理論知識

java反射詳解---反射的理論知識

此篇主要講解下反射的理論概念,另外一篇則是有很多的實際反射的例子,連結如下:

一、JAVA是動態語言嗎?

一般而言,說到動態言,都是指在程式執行時允許改變程式結構或者變數型別,從這個觀點看,JAVA和C++一樣,都不是動態語言。

但JAVA它卻有著一個非常突出的動態相關機制:反射。通過反射,Java可以於執行時載入、探知和使用編譯期間完全求和的類、生成其物件實體,呼叫其方法或者對屬性設值。所以Java算是一個半動態的語言吧。

反射的概念:

在Java中的反射機制是指在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;

對於任意一個物件,都能夠呼叫它的任意一個方法;

這種動態獲取資訊以及動態呼叫物件方法的功能稱為Java語言的反射機制

二、動態性質

2.1、動態性質

  • 執行時生成物件例項;
  • 執行期間呼叫方法;
  • 執行時更改屬性

2.2、Java反射機制能實現的功能

  • 在執行時判斷任意一個物件所屬的類
  • 在執行時構造任意一個類的物件
  • 在執行時判斷任意一個類所具有的方法和屬性
  • 在執行時呼叫任意一個物件的方法
  • 生成動態代理

2.3、Java反射應用場合

在Java程式中許多物件在執行時都會出現兩種型別:編譯時型別和執行時型別

編譯時的型別由宣告該物件時使用的型別決定,執行時的型別由實際賦給物件的型別決定

如:

Person p =new Student();

編譯時型別為Person,而執行時為Student

除此之外,程式在執行時還可能接收到外部傳入的一個物件,該物件的編譯時型別為Object,但程式又需要呼叫該物件執行時型別的方法。為了這些問題程式需要在執行時發現物件和類的真實資訊。然而,如果編譯時根本無法預知該物件和類可能屬於哪些類,程式只依靠執行時資訊來發現該物件和類的真實資訊,此時就必須使用反射

三、Java反射API

反射API用來生成在當前JAVA虛擬機器中的類、介面或者物件的資訊。

  • Class類:反射的核心類,可以獲取類的屬性,方法等內容資訊。
  • Field類:Java.lang.reflect.表示類的屬性,可以獲取和設定類的中屬性值。
  • Method類:Java.lang.reflect。表示類的方法,它可以用來獲取類中方法的資訊或者執行方法
  • Construcor類:Java.lang.reflect。表示類的構造方法。

四、獲取Class物件方式

  • 呼叫某個物件的getClass()方法
Person p = new Person();
Class cla=p.getClass();
  • 呼叫某個類的class屬性來獲取該類對應的Class物件
Class cls=Person.class;
  • 使用Class類的forName()靜態方法
Class cla=Class.forName(“類的全路徑”);

附上程式碼示例:

package com.fusionskye.ezsonar.model.configcenter;

import com.fusionskye.ezsonar.model.stream.StreamRule;
import java.io.IOException;


class hello {
    public static void main(String[] a) throws IOException {
        // 1.利用物件呼叫getClass()方法獲取該物件的Class例項
        StreamRule streamRule = new StreamRule();
        String s = streamRule.getClass().getName();
        System.out.println(s);// 結果:com.fusionskye.ezsonar.model.stream.StreamRule

        // 2.使用Class的靜態方法forName(),用類的名字獲取一個Class例項(傳的引數是類的完整路徑名稱)
        try {
            Class c2 = Class.forName("com.fusionskye.ezsonar.model.stream.StreamRule");
            System.out.println(c2.getName());// 結果:com.fusionskye.ezsonar.model.stream.StreamRule
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 3.運用.calss的方式獲取Class例項(類)
        Class c3 = StreamRule.class;
        System.out.println(c3.getName());// 結果:com.fusionskye.ezsonar.model.stream.StreamRule

        // 4.運用.calss的方式獲取Class例項(基本型別)
        Class c4 = int.class;
        System.out.println(c4.getName()); // 結果:int

        // 5.運用.calss的方式獲取Class例項(基本資料型別的封裝類)
        Class c5 = Integer.TYPE;
        System.out.println(c5.getName()); // 結果:int

        Class c6 = Integer.class;
        System.out.println(c6.getName());// 結果:java.lang.Integer

    }
}