⑴ java反射機製作用
一、什麼是反射:
反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問、檢測和修改它本身狀態或行為的一種能力。這一概念的提出很快引發了計算機科學領域關於應用反射性的研究。它首先被程序語言的設計領域所採用,並在Lisp和面向對象方面取得了成績。其中LEAD/LEAD++ 、OpenC++ 、MetaXa和OpenJava等就是基於反射機制的語言。最近,反射機制也被應用到了視窗系統、操作系統和文件系統中。反射本身並不是一個新概念,盡管計算機科學賦予了反射概念新的含義。在計算機科學領域,反射是指一類應用,它們能夠自描述和自控制。也就是說,這類應用通過採用某種機制來實現對自己行為的描述(self-representation)和監測(examination),並能根據自身行為的狀態和結果,調整或修改應用所描述行為的狀態和相關的語義。二、什麼是Java中的類反射:
Reflection 是 Java 程序開發語言的特徵之一,它允許運行中的 Java 程序對自身進行檢查,或者說「自審」,並能直接操作程序的內部屬性和方法。Java 的這一能力在實際應用中用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。
Reflection 是 Java 被視為動態(或准動態)語言的關鍵,允許程序於執行期 Reflection APIs 取得任何已知名稱之 class 的內部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可於執行期生成instances、變更 fields 內容或喚起 methods。三、Java類反射中所必須的類:
Java的類反射所需要的類並不多,它們分別是:Field、Constructor、Method、Class、Object,下面我將對這些類做一個簡單的說明。
Field類:提供有關類或介面的屬性的信息,以及對它的動態訪問許可權。反射的欄位可能是一個類(靜態)屬性或實例屬性,簡單的理解可以把它看成一個封裝反射類的屬性的類。
Constructor類:提供關於類的單個構造方法的信息以及對它的訪問許可權。這個類和Field類不同,Field類封裝了反射類的屬性,而Constructor類則封裝了反射類的構造方法。
Method類:提供關於類或介面上單獨某個方法的信息。所反映的方法可能是類方法或實例方法(包括抽象方法)。 這個類不難理解,它是用來封裝反射類方法的一個類。
Class類:類的實例表示正在運行的 Java 應用程序中的類和介面。枚舉是一種類,注釋是一種介面。每個數組屬於被映射為 Class 對象的一個類,所有具有相同元素類型和維數的數組都共享該 Class 對象。
Object類:每個類都使用 Object 作為超類。所有對象(包括數組)都實現這個類的方法。四、Java的反射類能做什麼:
看完上面的這么多我想你已經不耐煩了,你以為我在浪費你的時間,那麼好吧!下面我們就用一些簡單的小例子來說明它。
首先我們來看一下通過Java的反射機制我們能得到些什麼。
首先我們來寫一個類:java 代碼
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
class A extends Object implements ActionListener{
private int a = 3;
public Integer b = new Integer(4);
public A(){}
public A(int id,String name){}
public int abc(int id,String name){return 0;}
public void actionPerformed(ActionEvent e){}
} 你可能被我這個類弄糊塗了,你看不出我要做什麼,那就不要看這個類了,這個類是用來測試的,你知道知道它繼承了Object類,有一個介面是ActionListener,兩個屬性int和Integer,兩個構造方法和兩個方法,這就足夠了。
下面我們把A這個類作為一個反射類,來過去A類中的一些信息,首先我們先來過去一下反射類中的屬性和屬性值。java 代碼
import java.lang.reflect.*;
class B{
public static void main(String args[]){
A r = new A();
Class temp = r.getClass();
try{
System.out.println("反射類中所有公有的屬性");
Field[] fb =temp.getFields();
for(int j=0;j<fb.length;j++){
Class cl = fb[j].getType();
System.out.println("fb:"+cl);
}
System.out.println("反射類中所有的屬性");
Field[] fa = temp.getDeclaredFields();
for(int j=0;j<fa.length;j++){
Class cl = fa[j].getType();
System.out.println("fa:"+cl);
}
System.out.println("反射類中私有屬性的值");
Field f = temp.getDeclaredField("a");
f.setAccessible(true);
Integer i = (Integer)f.get(r);
System.out.println(i);
}catch(Exception e){
e.printStackTrace();
}
}
} 這里用到了兩個方法,getFields()、getDeclaredFields(),它們分別是用來獲取反射類中所有公有屬性和反射類中所有的屬性的方法。另外還有getField(String)和getDeclaredField(String)方法都是用來過去反射類中指定的屬性的方法,要注意的是getField方法只能取到反射類中公有的屬性,而getDeclaredField方法都能取到。
這里還用到了Field 類的setAccessible方法,它是用來設置是否有許可權訪問反射類中的私有屬性的,只有設置為true時才可以訪問,默認為false。另外 Field類還有set(Object AttributeName,Object value)方法,可以改變指定屬性的值。下面我們來看一下如何獲取反射類中的構造方法java 代碼
import java.lang.reflect.*;
public class SampleConstructor {
public static void main(String[] args) {
A r = new A();
printConstructors(r);
}
public static void printConstructors(A r) {
Class c = r.getClass();
//獲取指定類的類名
String className = c.getName();
try {
//獲取指定類的構造方法
Constructor[] theConstructors = c.getConstructors();
for(int i=0; i<theConstructors.length; i++) {
//獲取指定構造方法的參數的集合
Class[] parameterTypes = theConstructors[i].getParameterTypes();
System.out.print(className + "(");
for(int j=0; j<parameterTypes.length; j++)
System.out.print(parameterTypes[j].getName() + " ");
System.out.println(")");
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
這個例子很簡單,只是用getConstructors()方法獲取了反射類的構造方法的集合,並用Constructor類的getParameterTypes()獲取該構造方法的參數。下面我們再來獲取一下反射類的父類(超類)和介面java 代碼
import java.io.*;
import java.lang.reflect.*;
public class SampleInterface {
public static void main(String[] args) throws Exception {
A raf = new A();
printInterfaceNames(raf);
}
public static void printInterfaceNames(Object o) {
Class c = o.getClass();
//獲取反射類的介面
Class[] theInterfaces = c.getInterfaces();
for(int i=0; i<theInterfaces.length; i++)
System.out.println(theInterfaces[i].getName());
//獲取反射類的父類(超類)
Class theSuperclass = c.getSuperclass();
System.out.println(theSuperclass.getName());
}
} 這個例子也很簡單,只是用Class類的getInterfaces()方法獲取反射類的所有介面,由於介面可以有多個,所以它返回一個 Class數組。用getSuperclass()方法來獲取反射類的父類(超類),由於一個類只能繼承自一個類,所以它返回一個Class對象。下面我們來獲取一下反射類的方法java 代碼
import java.lang.reflect.*;
public class SampleMethod {
public static void main(String[] args) {
A p = new A();
printMethods(p);
}
public static void printMethods(Object o) {
Class c = o.getClass();
String className = c.getName();
Method[] m = c.getMethods();
for(int i=0; i<m.length; i++) {
//輸出方法的返回類型
System.out.print(m[i].getReturnType().getName());
//輸出方法名
System.out.print(" "+m[i].getName()+"(");
//獲取方法的參數
Class[] parameterTypes = m[i].getParameterTypes();
for(int j=0; j<parameterTypes.length; j++){
System.out.print(parameterTypes[j].getName());
if(parameterTypes.length>j+1){
System.out.print(",");
}
}
System.out.println(")");
}
}
} 這個例子並不難,它只是獲得了反射類的所有方法,包括繼承自它父類的方法。然後獲取方法的返回類型、方法名和方法參數。接下來讓我們回過頭來想一想,我們獲取了反射類的屬性、構造方法、父類、介面和方法,可這些東西能幫我們做些什麼呢!!
下面我寫一個比較完整的小例子,來說明Java的反射類能做些什麼吧!!java 代碼
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class LoadMethod {
public Object Load(String cName,String MethodName,String[] type,String[] param){
Object retobj = null;
try {
//載入指定的Java類
Class cls = Class.forName(cName);
//獲取指定對象的實例
Constructor ct = cls.getConstructor(null);
Object obj = ct.newInstance(null);
//構建方法參數的數據類型
Class partypes[] = this.getMethodClass(type);
//在指定類中獲取指定的方法
Method meth = cls.getMethod(MethodName, partypes);
//構建方法的參數值
Object arglist[] = this.getMethodObject(type,param);
//調用指定的方法並獲取返回值為Object類型
retobj= meth.invoke(obj, arglist);
}
catch (Throwable e) {
System.err.println(e);
}
return retobj;
}
//獲取參數類型Class[]的方法
public Class[] getMethodClass(String[] type){
Class[] cs = new Class[type.length];
for (int i = 0; i < cs.length; i++) {
if(!type[i].trim().equals("")||type[i]!=null){
if(type[i].equals("int")||type[i].equals("Integer")){
cs[i]=Integer.TYPE;
}else if(type[i].equals("float")||type[i].equals("Float")){
cs[i]=Float.TYPE;
}else if(type[i].equals("double")||type[i].equals("Double")){
cs[i]=Double.TYPE;
}else if(type[i].equals("boolean")||type[i].equals("Boolean")){
cs[i]=Boolean.TYPE;
}else{
cs[i]=String.class;
}
}
}
return cs;
}
//獲取參數Object[]的方法
public Object[] getMethodObject(String[] type,String[] param){
Object[] obj = new Object[param.length];
for (int i = 0; i < obj.length; i++) {
if(!param[i].trim().equals("")||param[i]!=null){
if(type[i].equals("int")||type[i].equals("Integer")){
obj[i]= new Integer(param[i]);
}else if(type[i].equals("float")||type[i].equals("Float")){
obj[i]= new Float(param[i]);
}else if(type[i].equals("double")||type[i].equals("Double")){
obj[i]= new Double(param[i]);
}else if(type[i].equals("boolean")||type[i].equals("Boolean")){
obj[i]=new Boolean(param[i]);
}else{
obj[i] = param[i];
}
}
}
return obj;
}
} 這是我在工作中寫的一個實現Java在運行時載入指定的類,並調用指定方法的一個小例子。這里沒有main方法,你可以自己寫一個。
Load方法接收的五個參數分別是,Java的類名,方法名,參數的類型和參數的值。結束語:
Java語言反射提供一種動態鏈接程序組件的多功能方法。它允許程序創建和控制任何類的對象,無需提前硬編碼目標類。這些特性使得反射特別適用於創建以非常普通的方式與對象協作的庫。Java reflection 非常有用,它使類和數據結構能按名稱動態檢索相關信息,並允許在運行著的程序中操作這些信息。Java 的這一特性非常強大,並且是其它一些常用語言,如 C、C++、Fortran 或者 Pascal 等都不具備的。但反射有兩個缺點。第一個是性能問題。用於欄位和方法接入時反射要遠慢於直接代碼。性能問題的程度取決於程序中是如何使用反射的。如果它作為程序運行中相對很少涉及的部分,緩慢的性能將不會是一個問題。即使測試中最壞情況下的計時圖顯示的反射操作只耗用幾微秒。僅反射在性能關鍵的應用的核心邏輯中使用時性能問題才變得至關重要。
⑵ Java的反射機制是什麼,如何實現
Java中的反射機制,通俗點解釋就是能夠在程序運行中動態獲取到內存中任一對象的信息,這些信息包括對象所屬類、類中的方法和屬性、以及它們的訪問控制域和返回值類型等等,還可以通過反射動態調用對象中的方法,而不管該方法的訪問域是私有或是公開,包括構造方法,還能實現動態代理等。總之,反射能夠破壞掉JAVA類本身的封裝性,進而獲取其私有的或公開的信息,也就能突破封裝進而調用私有的或公開的方法。
實現的話就是通過反射介面,JAVA把反射相關的類介面都封裝在了java.lang.reflect這個包中,你可以研究下這個包中的類,對於類的每一個屬性,如變數、方法,構造方法,這個包中都就與之相對應的類,通過這個類就可以操作這個屬性了。
java反射很強大,但也很危險,在實際開發中應少用或不用,在必要用之時,往往也能解決你遇到的問題。
⑶ java反射機制的實現原理
反射機制就是java語言在運行時擁有一項自觀的能力。
通過這種能力可以徹底的了解自身的情況為下一步的動作做准備。
下面具體介紹一下java的反射機制。這里你將顛覆原來對java的理解。
Java的反射機制的實現要藉助於4個類:class,Constructor,Field,Method;
其中class代表的時類對象,
Constructor-類的構造器對象,
Field-類的屬性對象,
Method-類的方法對象。
通過這四個對象我們可以粗略的看到一個類的各個組成部分。
Class:程序運行時,java運行時系統會對所有的對象進行運行時類型的處理。
這項信息記錄了每個對象所屬的類,虛擬機通常使用運行時類型信息選擇正 確的方法來執行(摘自:白皮書)。
但是這些信息我們怎麼得到啊,就要藉助於class類對象了啊。
在Object類中定義了getClass()方法。我 們可以通過這個方法獲得指定對象的類對象。然後我們通過分析這個對象就可以得到我們要的信息了。
比如:ArrayList arrayList;
Class clazz = arrayList.getClass();
然後我來處理這個對象clazz。
當然了Class類具有很多的方法,這里重點將和Constructor,Field,Method類有關系的方法。
Reflection 是 Java 程序開發語言的特徵之一,它允許運行中的 Java 程序對自身進行檢查,或者說「自審」,並能直接操作程序的內部屬性。Java 的這一能力在實際應用中也許用得不是很多,但是個人認為要想對java有個更加深入的了解還是應該掌握的。
reflection的工作機制
考慮下面這個簡單的例子,讓我們看看 reflection 是如何工作的。
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[]) {
try {
//forName("java.lang.String")獲取指定的類的對象
Class c = Class.forName("java.lang.String");
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);
}
}
}
按如下語句執行:
java DumpMethods java.util.ArrayList
這個程序使用 Class.forName 載入指定的類,然後調用 getDeclaredMethods 來獲取這個類中定義了的方法列表。java.lang.reflect.Methods 是用來描述某個類中單個方法的一個類。
Java類反射中的主要方法
對於以下三類組件中的任何一類來說
-- 構造函數、欄位和方法
-- java.lang.Class 提供四種獨立的反射調用,以不同的方式來獲得信息。調用都遵循一種標准格式。以下是用於查找構造函數的一組反射調用:
Constructor getConstructor(Class[] params) -- 獲得使用特殊的參數類型的公共構造函數,
Constructor[] getConstructors() -- 獲得類的所有公共構造函數
Constructor getDeclaredConstructor(Class[] params) -- 獲得使用特定參數類型的構造函數(與接入級別無關)
Constructor[] getDeclaredConstructors() -- 獲得類的所有構造函數(與接入級別無關)
獲得欄位信息的Class 反射調用不同於那些用於接入構造函數的調用,在參數類型數組中使用了欄位名:
Field getField(String name) -- 獲得命名的公共欄位
Field[] getFields() -- 獲得類的所有公共欄位
Field getDeclaredField(String name) -- 獲得類聲明的命名的欄位
Field[] getDeclaredFields() -- 獲得類聲明的所有欄位
用於獲得方法信息函數:
Method getMethod(String name, Class[] params) -- 使用特定的參數類型,獲得命名的公共方法
Method[] getMethods() -- 獲得類的所有公共方法
Method getDeclaredMethod(String name, Class[] params) -- 使用特寫的參數類型,獲得類聲明的命名的方法
Method[] getDeclaredMethods() -- 獲得類聲明的所有方法
使用 Reflection:
用於 reflection 的類,如 Method,可以在 java.lang.relfect 包中找到。使用這些類的時候必須要遵循三個步驟:
第一步是獲得你想操作的類的 java.lang.Class 對象。
在運行中的 Java 程序中,用 java.lang.Class 類來描述類和介面等。
下面就是獲得一個 Class 對象的方法之一:
Class c = Class.forName("java.lang.String");
這條語句得到一個 String 類的類對象。還有另一種方法,如下面的語句:
Class c = int.class;
或者
Class c = Integer.TYPE;
它們可獲得基本類型的類信息。其中後一種方法中訪問的是基本類型的封裝類 (如 Intege ) 中預先定義好的 TYPE 欄位。
第二步是調用諸如 getDeclaredMethods 的方法,以取得該類中定義的所有方法的列表。
一旦取得這個信息,就可以進行第三步了——使用 reflection API 來操作這些信息,如下面這段代碼:
Class c = Class.forName("java.lang.String");
Method m[] = c.getDeclaredMethods();
System.out.println(m[0].toString());
它將以文本方式列印出 String 中定義的第一個方法的原型。
處理對象:
a.創建一個Class對象
b.通過getField 創建一個Field對象
c.調用Field.getXXX(Object)方法(XXX是Int,Float等,如果是對象就省略;Object是指實例).
例如:
import java.lang.reflect.*;
import java.awt.*;
class SampleGet {
public static void main(String[] args) throws Exception {
Rectangle r = new Rectangle(100, 325);
printHeight(r);
printWidth( r);
}
static void printHeight(Rectangle r)throws Exception {
//Field屬性名
Field heightField;
//Integer屬性值
Integer heightValue;
//創建一個Class對象
Class c = r.getClass();
//.通過getField 創建一個Field對象
heightField = c.getField("height");
//調用Field.getXXX(Object)方法(XXX是Int,Float等,如果是對象就省略;Object是指實例).
heightValue = (Integer) heightField.get(r);
System.out.println("Height: " + heightValue.toString());
}
static void printWidth(Rectangle r) throws Exception{
Field widthField;
Integer widthValue;
Class c = r.getClass();
widthField = c.getField("width");
widthValue = (Integer) widthField.get(r);
System.out.println("Height: " + widthValue.toString());
}
}
⑷ 能說一下java的反射機制嗎
反射:一個類有多個組成部分,例如:成員變數、方法、構造方法等
反射就是載入類,並解剖出類的各個組成部分
java中有一個Class類用於代表某一個類的位元組碼。Class類提供載入某個位元組碼的方法:forName()
forName方法用於載入某個類的位元組碼到內存中,並使用Class對象進行封裝
另外兩種得到Class對象的方式:
類名.class
對象。getClass()
SUN公司為簡化創建對象的方法,它在Class對象中也提供了一個newInstance方法,用於創建類的對象,這樣開發人員可以避免每次都需要去反射Constructor類以創建對象
不過需要注意的是,Class.newInstance方法內部是反射類無參的構造函數創建的對象,所以利用此種方式創建類對象時,類必須有一個無參的構造函數
總結如下:反射機制是開發框架時才運用到的技術
⑸ java反射機制的作用(java中反射機制的作用)
怎麼理解Java中的反射,作用是什麼1、JAVA中反射是動態獲取信息以及動態調用對象方法的一種反射機制。Java反射就是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。
2、Java的反射(reflection)機制是指在程序的運行狀態中,可以構造任意一個類的對象,可以了解任意一個對象所屬的類,可以了解任意一個類的成員變數和方法,可以調用任意一個對象的屬性和方法。
3、反射就是把java類中的各種成分映射成為相應的java類。
4、java的反射機制就是增加程序的靈活性,避免將程序寫死到代碼里,例如:實例化一個person()對象,不使用反射,newperson();如果想變成實例化其他類,那麼必須修改源代碼,並重新編譯。
5、Java語言反射提供一種動態鏈接程序組件的多功能方法。它允許程序創建和控制任何類的對象(根據安全性限制),無需提前硬編碼目標類。這些特性使得反射特別適用於創建以非常普通的方式與對象協作的庫。
java的反射機制用處在哪?1、盡管在這樣的定義與分類下Java不是動態語言,它卻有著一個非常突出的動態相關機制:Reflection。這個字的意思是「反射、映象、倒影」,用在Java身上指的是我們可以於運行時載入、探知、使用編譯期間完全未知的classes。
2、在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變數和方法;在運行時調用任意一個對象的方法;生成動態代理。JAVA有著一個非常突出的動態相關機制:Reflection。
3、Java反射機制主要用於實現以下功能。(1)在運行時判斷任意一個對象所屬的類型。(2)在運行時構造任意一個類的對象。(3)在運行時判斷任意一個類所具有的成員變數和方法。
java反射的作用。1、Java反射機制主要提供了以下功能:在運行時判斷任意一個對象所屬的類;在運行時構造任意一個類的對象;在運行時判斷任意一個類所具有的成員變數和方法;在運行時調用任意一個對象的方法;生成動態代理。
2、如果你是方法,快遞員是虛擬機。快遞員通過地址查地圖找你的叫反射調用。直接去找你的叫直接調用。反射很多地方在用,代碼編輯器智能提示就是反射的例子。
3、Java反射是Java被視為動態(或准動態)語言的一個關鍵性質。
java中的反射機制是什麼,有什麼作用啊?
反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
Java的反射機制是使其具有動態特性的非常關鍵的一種機制,也是在JavaBean中廣泛應用的一種特性。運用JavaBean的最常見的問題是:根據指定的類名,類欄位名和所對應的數據,得到該類的實例,下面的一個例子演示了這一實現。
JAVA中反射是動態獲取信息以及動態調用對象方法的一種反射機制。Java反射就是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。
如果你是方法,快遞員是虛擬機。快遞員通過地址查地圖找你的叫反射調用。直接去找你的叫直接調用。反射很多地方在用,代碼編輯器智能提示就是反射的例子。
Java的反射(reflection)機制是指在程序的運行狀態中,可以構造任意一個類的對象,可以了解任意一個對象所屬的類,可以了解任意一個類的成員變數和方法,可以調用任意一個對象的屬性和方法。
反射的概念是由Smith在1982年首次提出的,主要是指程序可以訪問、檢測和修改其本身狀態或行為的一種能力。
java中的反射可以做什麼Java語言反射提供一種動態鏈接程序組件的多功能方法。它允許程序創建和控制任何類的對象(根據安全性限制),無需提前硬編碼目標類。這些特性使得反射特別適用於創建以非常普通的方式與對象協作的庫。
JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
如果你是方法,快遞員是虛擬機。快遞員通過地址查地圖找你的叫反射調用。直接去找你的叫直接調用。反射很多地方在用,代碼編輯器智能提示就是反射的例子。
什麼是JAVA的反射機制?有什麼作用?1、反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。
2、Java的反射機制是使其具有動態特性的非常關鍵的一種機制,也是在JavaBean中廣泛應用的一種特性。運用JavaBean的最常見的問題是:根據指定的類名,類欄位名和所對應的數據,得到該類的實例,下面的一個例子演示了這一實現。
3、JAVA中反射是動態獲取信息以及動態調用對象方法的一種反射機制。Java反射就是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。