java中的反射機制是什麼?有什麼作用呢?求解,謝謝。

  • 作者:由 匿名使用者 發表于 攝影
  • 2022-08-09

java中的反射機制是什麼?有什麼作用呢?求解,謝謝。網友f820e9a 2017-10-30

Java反射機制詳解

1. 反射機制是什麼

反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。

2. 反射機制能做什麼

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

在執行時判斷任意一個物件所屬的類;

在執行時構造任意一個類的物件;

在執行時判斷任意一個類所具有的成員變數和方法;

在執行時呼叫任意一個物件的方法;

生成動態代理。

3. 反射機制的相關API

透過一個物件獲得完整的包名和類名

package net。xsoftlab。baike;

public class TestReflect {

public static void main(String[] args) throws Exception {

TestReflect testReflect = new TestReflect();

System。out。println(testReflect。getClass()。getName());

// 結果 net。xsoftlab。baike。TestReflect

}

}

例項化Class類物件

package net。xsoftlab。baike;

public class TestReflect {

public static void main(String[] args) throws Exception {

Class<?> class1 = null;

Class<?> class2 = null;

Class<?> class3 = null;

// 一般採用這種形式

class1 = Class。forName(“net。xsoftlab。baike。TestReflect”);

class2 = new TestReflect()。getClass();

class3 = TestReflect。class;

System。out。println(“類名稱   ” + class1。getName());

System。out。println(“類名稱   ” + class2。getName());

System。out。println(“類名稱   ” + class3。getName());

}

}

獲取一個物件的父類與實現的介面

package net。xsoftlab。baike;

import java。io。Serializable;

public class TestReflect implements Serializable {

private static final long serialVersionUID = -2862585049955236662L;

public static void main(String[] args) throws Exception {

Class<?> clazz = Class。forName(“net。xsoftlab。baike。TestReflect”);

// 取得父類

Class<?> parentClass = clazz。getSuperclass();

System。out。println(“clazz的父類為:” + parentClass。getName());

// clazz的父類為: java。lang。Object

// 獲取所有的介面

Class<?> intes[] = clazz。getInterfaces();

System。out。println(“clazz實現的介面有:”);

for (int i = 0; i < intes。length; i++) {

System。out。println((i + 1) + “:” + intes[i]。getName());

}

// clazz實現的介面有:

// 1:java。io。Serializable

}

}

獲取某個類中的全部建構函式 - 詳見下例

透過反射機制例項化一個類的物件

package net。xsoftlab。baike;

import java。lang。reflect。Constructor;

public class TestReflect {

public static void main(String[] args) throws Exception {

Class<?> class1 = null;

class1 = Class。forName(“net。xsoftlab。baike。User”);

// 第一種方法,例項化預設構造方法,呼叫set賦值

User user = (User) class1。newInstance();

user。setAge(20);

user。setName(“Rollen”);

System。out。println(user);

// 結果 User [age=20, name=Rollen]

// 第二種方法 取得全部的建構函式 使用建構函式賦值

Constructor<?> cons[] = class1。getConstructors();

// 檢視每個構造方法需要的引數

for (int i = 0; i < cons。length; i++) {

Class<?> clazzs[] = cons[i]。getParameterTypes();

System。out。print(“cons[” + i + “] (”);

for (int j = 0; j < clazzs。length; j++) {

if (j == clazzs。length - 1)

System。out。print(clazzs[j]。getName());

else

System。out。print(clazzs[j]。getName() + “,”);

}

System。out。println(“)”);

}

// 結果

// cons[0] (java。lang。String)

// cons[1] (int,java。lang。String)

// cons[2] ()

user = (User) cons[0]。newInstance(“Rollen”);

System。out。println(user);

// 結果 User [age=0, name=Rollen]

user = (User) cons[1]。newInstance(20, “Rollen”);

System。out。println(user);

// 結果 User [age=20, name=Rollen]

}

}

class User {

private int age;

private String name;

public User() {

super();

}

public User(String name) {

super();

this。name = name;

}

public User(int age, String name) {

super();

this。age = age;

this。name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this。age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this。name = name;

}

@Override

public String toString() {

return “User [age=” + age + “, name=” + name + “]”;

}

}

獲取某個類的全部屬性

package net。xsoftlab。baike;

import java。io。Serializable;

import java。lang。reflect。Field;

import java。lang。reflect。Modifier;

public class TestReflect implements Serializable {

private static final long serialVersionUID = -2862585049955236662L;

public static void main(String[] args) throws Exception {

Class<?> clazz = Class。forName(“net。xsoftlab。baike。TestReflect”);

System。out。println(“===============本類屬性===============”);

// 取得本類的全部屬性

Field[] field = clazz。getDeclaredFields();

for (int i = 0; i < field。length; i++) {

// 許可權修飾符

int mo = field[i]。getModifiers();

String priv = Modifier。toString(mo);

// 屬性型別

Class<?> type = field[i]。getType();

System。out。println(priv + “ ” + type。getName() + “ ” + field[i]。getName() + “;”);

}

System。out。println(“==========實現的介面或者父類的屬性==========”);

// 取得實現的介面或者父類的屬性

Field[] filed1 = clazz。getFields();

for (int j = 0; j < filed1。length; j++) {

// 許可權修飾符

int mo = filed1[j]。getModifiers();

String priv = Modifier。toString(mo);

// 屬性型別

Class<?> type = filed1[j]。getType();

System。out。println(priv + “ ” + type。getName() + “ ” + filed1[j]。getName() + “;”);

}

}

}

透過反射機制呼叫某個類的方法

package net。xsoftlab。baike;

import java。lang。reflect。Method;

public class TestReflect {

public static void main(String[] args) throws Exception {

Class<?> clazz = Class。forName(“net。xsoftlab。baike。TestReflect”);

// 呼叫TestReflect類中的reflect1方法

Method method = clazz。getMethod(“reflect1”);

method。invoke(clazz。newInstance());

// Java 反射機制 - 呼叫某個類的方法1。

// 呼叫TestReflect的reflect2方法

method = clazz。getMethod(“reflect2”, int。class, String。class);

method。invoke(clazz。newInstance(), 20, “張三”);

// Java 反射機制 - 呼叫某個類的方法2。

// age -> 20。 name -> 張三

}

public void reflect1() {

System。out。println(“Java 反射機制 - 呼叫某個類的方法1。”);

}

public void reflect2(int age, String name) {

System。out。println(“Java 反射機制 - 呼叫某個類的方法2。”);

System。out。println(“age -> ” + age + “。 name -> ” + name);

}

}

透過反射機制操作某個類的屬性

package net。xsoftlab。baike;

import java。lang。reflect。Field;

public class TestReflect {

private String proprety = null;

public static void main(String[] args) throws Exception {

Class<?> clazz = Class。forName(“net。xsoftlab。baike。TestReflect”);

Object obj = clazz。newInstance();

// 可以直接對 private 的屬性賦值

Field field = clazz。getDeclaredField(“proprety”);

field。setAccessible(true);

field。set(obj, “Java反射機制”);

System。out。println(field。get(obj));

}

}

4. 反射機制的應用例項

在泛型為Integer的ArrayList中存放一個String型別的物件。

package net。xsoftlab。baike;

import java。lang。reflect。Method;

import java。util。ArrayList;

public class TestReflect {

public static void main(String[] args) throws Exception {

ArrayList list = new ArrayList();

Method method = list。getClass()。getMethod(“add”, Object。class);

method。invoke(list, “Java反射機制例項。”);

System。out。println(list。get(0));

}

}

透過反射取得並修改陣列的資訊

package net。xsoftlab。baike;

import java。lang。reflect。Array;

public class TestReflect {

public static void main(String[] args) throws Exception {

int[] temp = { 1, 2, 3, 4, 5 };

Class<?> demo = temp。getClass()。getComponentType();

System。out。println(“陣列型別: ” + demo。getName());

System。out。println(“陣列長度  ” + Array。getLength(temp));

System。out。println(“陣列的第一個元素: ” + Array。get(temp, 0));

Array。set(temp, 0, 100);

System。out。println(“修改之後陣列第一個元素為: ” + Array。get(temp, 0));

}

}

將反射機制應用於工廠模式

package net。xsoftlab。baike;

interface fruit {

public abstract void eat();

}

class Apple implements fruit {

public void eat() {

System。out。println(“Apple”);

}

}

class Orange implements fruit {

public void eat() {

System。out。println(“Orange”);

}

}

class Factory {

public static fruit getInstance(String ClassName) {

fruit f = null;

try {

f = (fruit) Class。forName(ClassName)。newInstance();

} catch (Exception e) {

e。printStackTrace();

}

return f;

}

}

/**

* 對於普通的工廠模式當我們在新增一個子類的時候,就需要對應的修改工廠類。 當我們新增很多的子類的時候,會很麻煩。

* Java 工廠模式可以參考

* http://baike。xsoftlab。net/view/java-factory-pattern

*

* 現在我們利用反射機制實現工廠模式,可以在不修改工廠類的情況下新增任意多個子類。

*

* 但是有一點仍然很麻煩,就是需要知道完整的包名和類名,這裡可以使用properties配置檔案來完成。

*

* java 讀取 properties 配置檔案 的方法可以參考

* http://baike。xsoftlab。net/view/java-read-the-properties-configuration-file

*

* @author xsoftlab。net

*/

public class TestReflect {

public static void main(String[] args) throws Exception {

fruit f = Factory。getInstance(“net。xsoftlab。baike。Apple”);

if (f != null) {

f。eat();

}

}

}

我有一個微信公眾號,經常會分享一些Java技術相關的乾貨,還有一些學習資源。

如果你喜歡我的分享,可以用微信搜尋“Java團長”或者“javatuanzhang”關注。

java中的反射機制是什麼?有什麼作用呢?求解,謝謝。紫eyes 2017-10-30

反射是java的一種動態執行機制,常見框架底層用的都是反射,隨需而變就是反射,簡單的講,和動態沾邊的都是反射。

反射在什麼時候用呢?

(1)當能確定呼叫執行關係時,不用反射

(2)當出現不確定的情況(不知道類名,不知道屬性名,不知道方法名),就可以使用反射

特殊用途:利用反射訪問私有屬性方法

java中的反射機制是什麼?有什麼作用呢?求解,謝謝。CodingSir 2021-03-28

Java反射-屬性操作

java中的反射機制是什麼?有什麼作用呢?求解,謝謝。網友d8a1812 2017-10-31

JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。

JAVA反射(放射)機制:“程式執行時,允許改變程式結構或變數型別,這種語言稱為動態語言”。從這個觀點看,Perl,Python,Ruby是動態語言,C++,Java,C#不是動態語言。但是JAVA有著一個非常突出的動態相關機制:Reflection,用在Java身上指的是我們可以於執行時載入、探知、使用編譯期間完全未知的classes。換句話說,Java程式可以載入一個執行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其物件實體、或對其fields設值、或喚起其methods。

Java反射機制主要提供了以下功能: 在執行時判斷任意一個物件所屬的類;在執行時構造任意一個類的物件;在執行時判斷任意一個類所具有的成員變數和方法;在執行時呼叫任意一個物件的方法;生成動態代理。

有時候我們說某個語言具有很強的動態性,有時候我們會區分動態和靜態的不同技術與作法。我們朗朗上口動態繫結(dynamic binding)、動態連結(dynamic linking)、動態載入(dynamic loading)等。然而“動態”一詞其實沒有絕對而普遍適用的嚴格定義,有時候甚至像面向物件當初被匯入程式設計領域一樣,一人一把號,各吹各的調。

一般而言,開發者社群說到動態語言,大致認同的一個定義是:“程式執行時,允許改變程式結構或變數型別,這種語言稱為動態語言”。從這個觀點看,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 APIs,也就是讓讀者知道如何探索class的結構、如何對某個“執行時才獲知名稱的class”生成一份實體、為其fields設值、呼叫其methods。本文將談到java。lang。Class,以及java。lang。reflect中的Method、Field、Constructor等等classes。

java中的反射機制是什麼?有什麼作用呢?求解,謝謝。難學也要學下去 2017-10-30

JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法;這種動態獲取的以及動態呼叫物件的方法的功能稱為java語言的反射機制。

Java反射機制主要提供了以下功能:在執行時判定任意一個物件所屬的類;在執行時構造任意一個類的物件;在執行時判定任意一個類所具有的成員變數和方法;在執行時呼叫任意一個物件的方法;生成動態代理。

Top