java中的反射,java中的反射有什麼作用

本文目錄一覽:

北大青鳥java培訓:Java的反射機制?

Java反射機制是一個非常強大的功能,在很多大型項目比如Spring,Mybatis都可以看見反射的身影。

通過反射機制我們可以在運行期間獲取對象的類型信息,利用這一特性我們可以實現工廠模式和代理模式等設計模式,同時也可以解決Java泛型擦除等令人苦惱的問題。

下面java課程就從實際應用的角度出發,來應用一下Java的反射機制。

反射基礎p.s:本文需要讀者對反射機制的API有一定程度的了解,如果之前沒有接觸過的話,建議先看一下官方文檔的QuickStart。

在應用反射機制之前,首先我們先來看一下如何獲取一個對象對應的反射類Class,在Java中我們有三種方法可以獲取一個對象的反射類。

通過getClass方法在Java中,每一個Object都有一個getClass方法,通過getClass方法我們可以獲取到這個對象對應的反射類:Strings=”ziwenxie”;Class?c=s.getClass();通過forName方法我們也可以調用Class類的靜態方法forName:Class?c=Class.forName(“java.lang.String”);使用.class或者我們也可以直接使用.class:Class?c=String.class;獲取類型信息在文章開頭我們就提到反射的一大好處就是可以允許我們在運行期間獲取對象的類型信息,下面我們通過一個例子來具體看一下。

首先我們在typeinfo.interfacea包下面新建一個接口A:packagetypeinfo.interfacea;publicinterfaceA{voidf();}接着我們在typeinfo.packageaccess包下面新建一個接口C,接口C繼承自接口A,並且我們還另外創建了幾個用於測試的方法,注意下面幾個方法的權限都是不同的。

java中的反射可以做什麼

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

在運行時判斷任意一個對象所屬的類;

在運行時構造任意一個類的對象;

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

在運行時調用任意一個對象的方法;生成動態代理。

JAVA有着一個非常突出的動態相關機制:Reflection。

這個字的意思是“反射、映象、倒影”,用在Java身上指的是我們可以於運行時加載、探知、使用編譯期間完全未知的classes。換句話說,Java程序可以加載一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods。這種“看透class”的能力(the ability of the program to examine itself)被稱為introspection(內省、內觀、反省)。Reflection和introspection是常被並提的兩個術語。

什麼是java的反射

Java反射指的是對於任何的一個java類,我們都可以通過反射獲取到這個類的所有屬性和方法(包含私有的屬性方法),使用java反射我們也可以調用一個對象的任何方法。

我們知道Java是一門面向對象編程的語言,我們編程的時候,經常會將類的屬性進行封裝,然後提供public方法進行屬性的設置和獲取。類的屬性我們通常會設置成private的私有屬性,為的就是保護對象屬性不被隨意的修改和訪問。但是反射機制卻恰恰相反,通過反射,我們可以獲取到這些被保護的屬性和方法,並且可以修改和訪問他們。

在java中我們可以使用object對象的getClass();方法獲得Class的對象classObject;語法格式為 Class classObject = object.getClass() ;可以根據Class對象的方法獲取object對象的相關屬性和方法;

獲取object對象的名字可以使用 classObject.getName();獲取類的名稱,獲取到的結果包含包的名稱;

獲取object對象的包名稱,可以使用classObject.getPackage();獲取包的名稱;

獲取object對象的所有public屬性,可以使用classObject.getFields();方法,返回列表是屬性類Field[]對象列表;

獲取object對象所有屬性,可以使用classObject.getDeclaredFields();方法,返回的是所有屬性列表(包含private屬性);

獲取object對象某個特定的屬性,可以使用classObject.getField( fieldName );可以根據屬性名稱獲取屬性類的對象;

獲取object對象private屬性,可以使用classObject.getDeclaredField( fieldName );根據屬性名獲取屬性對象信息;

獲取object對象public方法,使用classObject.getMethods();可以獲取到方法類Method[]對象列表;

獲取object對象某個特定的public方法,使用classObject.getMethod( funName , Class… parameterTypes);根據方法名和方法參數類型列表,可以獲取到方法類的對象;

獲取object對象所有方法(包含private方法);使用classObject.getDeclaredMethods();可以獲取所有的方法對象列表;

獲取object對象某個特定方法(包含private方法),使用classObject.getDeclaredMethod ( funName, Class… parameterTypes );根據方法名和方法參數類型列表,可以獲取到類的特定方法(包含private方法);

獲取object對象類中所有的public構造方法,可以使用classObject.getConstructors(); 獲取到構造類Constructor的對象列表;

獲取object對象類中某個特定的構造方法,可以使用classObject.getConstructor( Class… parameterTypes ); 根據參數類型列表,獲取指定的構造函數對象;

獲取object對象類中所有的構造方法(包含private),可以使用classObject.getDeclaredConstructors(); 獲取到構造類Constructor的對象列表;

獲取object對象類中某個特定的構造方法(包含private),可以使用classObject.getDeclaredConstructor( Class… parameterTypes ); 根據參數類型列表,獲取指定的構造函數對象;

Java裡面反射的原理是什麼?

Java在編譯之後會生成一個class文件,反射通過字節碼文件找到其類中的方法和屬性等。

通過反射,java可以動態的加載未知的外部配置對象,臨時生成字節碼進行加載使用,使代碼更靈活,極大地提高應用的擴展性。

其實博客會有更加詳細的解釋。

java反射機制詳解

反射就是把Java的各種成分映射成相應的Java類。

Class類的構造方法是private,由JVM創建。

反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查並且對內部的成員進行操作。例如它允許一個java的類獲取他所有的成員變量和方法並且顯示出來。Java 的這一能力在實際應用中也許用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。(來自Sun)

JavaBean 是 reflection 的實際應用之一,它能讓一些工具可視化的操作軟件組件。這些工具通過 reflection 動態的載入並取得 Java 組件(類) 的屬性。

反射是從1.2就有的,後面的三大框架都會用到反射機制,涉及到類”Class”,無法直接new CLass(),其對象是內存里的一份字節碼.

Class 類的實例表示正在運行的 Java 應用程序中的類和接口。枚舉是一種類,注釋是一種接口。每個數組屬於被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。

基本的 Java類型(boolean、byte、char、short、int、long、float 和 double)和關鍵字 void 也表示為 Class 對象。Class 沒有公共構造方法。

Class 對象是在加載類時由 Java 虛擬機以及通過調用類加載器中的 defineClass 方法自動構造的。

Person p1 = new Person();

//下面的這三種方式都可以得到字節碼

CLass c1 = Date.class();

p1.getClass();

//若存在則加載,否則新建,往往使用第三種,類的名字在寫源程序時不需要知道,到運行時再傳遞過來

Class.forName(“java.lang.String”);

Class.forName()字節碼已經加載到java虛擬機中,去得到字節碼;java虛擬機中還沒有生成字節碼 用類加載器進行加載,加載的字節碼緩衝到虛擬機中。 

另外,大家可以關注微信公眾號Java技術棧回復:JVM,獲取我整理的系列JVM教程,都是乾貨。

考慮下面這個簡單的例子,讓我們看看 reflection 是如何工作的。

import java.lang.reflect.*;

public class DumpMethods {

public static void main(String args[]) {

try {

Class c = Class.forName(“java.util.Stack”);

Method m[] = c.getDeclaredMethods();

for (int i = 0; i m.length; i++)

System.out.println(m[i].toString());

}

catch (Throwable e){

System.err.println(e);

}

}

}

public synchronized java.lang.Object java.util.Stack.pop()

public java.lang.Object java.util.Stack.push(java.lang.Object)

public boolean java.util.Stack.empty()

public synchronized java.lang.Object java.util.Stack.peek()

public synchronized int java.util.Stack.search(java.lang.Object)

這樣就列出了java.util.Stack 類的各方法名以及它們的限制符和返回類型。這個程序使用 Class.forName 載入指定的類,然後調用 getDeclaredMethods 來獲取這個類中定義了的方法列表。java.lang.reflect.Methods 是用來描述某個類中單個方法的一個類。

以下示例使用 Class 對象來顯示對象的類名:

void printClassName(Object obj) {

System.out.println(“The class of ” + obj +

” is ” + obj.getClass().getName());

}

還可以使用一個類字面值(JLS Section 15.8.2)來獲取指定類型(或 void)的 Class 對象。例如:

System.out.println(“The name of class Foo is: “+Foo.class.getName());

在沒有對象實例的時候,主要有兩種辦法。

//獲得類類型的兩種方式

Class cls1 = Role.class;

Class cls2 = Class.forName(“yui.Role”);

注意第二種方式中,forName中的參數一定是完整的類名(包名+類名),並且這個方法需要捕獲異常。現在得到cls1就可以創建一個Role類的實例了,利用Class的newInstance方法相當於調用類的默認的構造器。

Object o = cls1.newInstance();

//創建一個實例

//Object o1 = new Role(); //與上面的方法等價

java反射的作用。

1. Java反射包reflection提供對Class,Method,field,constructor1 等信息的封裝類型。

2. 通過這些api可以輕易獲得一個類的各種信息並且可以進行實例化,方法調用等。

類中的private參數可以通過setaccessible方法強制獲取。

3. 反射的作用可謂是博大精深,JDK動態代理生成代理類的字節碼後,首先把這個類通過defineclass定義成一個類,然後用class.for(name)會把該類加載到jvm,之後我們就可以通過,A.class.GetMethod()獲取其方法,然後通過invoke調用其方法,在調用這個方法時,實際上會通過被代理類的引用再去調用原方法。

原創文章,作者:ONYK,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/145376.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ONYK的頭像ONYK
上一篇 2024-10-27 23:49
下一篇 2024-10-27 23:49

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • Python中init方法的作用及使用方法

    Python中的init方法是一個類的構造函數,在創建對象時被調用。在本篇文章中,我們將從多個方面詳細討論init方法的作用,使用方法以及注意點。 一、定義init方法 在Pyth…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29

發表回復

登錄後才能評論