導航:首頁 > 編程語言 > java反射構造函數

java反射構造函數

發布時間:2024-07-25 18:16:00

『壹』 java中的反射機制是什麼,有什麼作用啊

Method類中的方法的使用(含代碼和注釋):

getMethods()獲得本類及父類中的public許可權修飾**符方法
getDeclaredMethods()專門獲得調用該方法的對象的本類中的所有方法包括private許可權修飾符**的方法
getDeclaredMethod(Stringname,class<?>...parameterTypes)
第一個參數:方法的名稱
第二個參數:可變長度,寫你要查找的那個方法的參數類型列表.class
getParameterCount()得到方法的參數個數123456
packageLessonForReflection03;importjava.lang.reflect.Method;importjava.lang.reflect.Modifier;abstractclassCard{
privatevoidcreatRandomNumbers(intcount)//private關鍵字
{

}

publicvoidgetFullCardsNumbers(String[]random,Stringpre_numbers)
{

}

publicstaticvoidgetUserInfor()
{

}

(Stringtel);

(intsal1,intsal2),ArithmeticException;}publicclassMethodInforGetter{

publicstaticvoidmain(String[]args)
{
Class<?>c1=Card.class;

System.out.println("-------------------------");

Method[]m1=c1.getMethods();//getMethods()獲得本類及父類中的public方法!
for(Methodm:m1)
{
System.out.println(m);
}

System.out.println("-------------------------");

Method[]m2=c1.getDeclaredMethods();//getDeclaredMethods()專門獲得本類中的所有方法包括private!
for(Methodm:m2)
{
System.out.println(m);
}

System.out.println("-------------------------");

/*
*getDeclaredMethod(Stringname,class<?>...parameterTypes)
*第一個參數:方法的名稱
*第二個參數:可變長度,寫你要查找的那個方法的參數類型列表
*
*getParameterCount()得到方法的參數個數
*/

try
{
Methodm3=c1.getDeclaredMethod("getUserInfor");
System.out.println(m3);

//getParameterCount()方法,獲得方法參數個數
System.out.println(m3.getParameterCount());
System.out.println(Modifier.toString(m3.getModifiers()));//獲得方法修飾符
System.out.println(m3.getReturnType());

System.out.println("-------------------------");

Methodm4=c1.getDeclaredMethod("getUserInfor",int.class,int.class);

//getExceptionTypes()可以獲得初始化當前Method對象的給Class對象初始化的那個類的那個指定方法拋出的異常類型
Class<?>[]exception=m4.getExceptionTypes();
for(Class<?>e:exception)
{
System.out.println(e);
}

}catch(NoSuchMethodException|SecurityExceptione)
{
e.printStackTrace();
}
}}576777879808182838485868788

Constructor類中的方法的使用www.xiaoyuani.com(含代碼和注釋):

java.lang.reflect.Constructor:
Constructor[]getConstructor()獲得本類里的public許可權修飾符構造函數,不能獲取父類的!
Constructor[]getDeclaredConstructor()獲得本類中的所以構造函數!
Constructor<T>getConstructor(Class...parameterType)用參數決定獲得本類中的某個的構造方法,只能獲得public的
Constructor<T>getDeclaredConstructor(Class...parameterType)用參數決定獲得本類中的某個構造方法
附:
JDK8.0之後新增的類:
Executable:
它是Method和Constructor的父類
常用方法:
getParameter()獲得類中方法參數
getExceptionTypes()獲得類中某個方法拋出異常類型
getMoidfiers()獲得方法許可權修飾符
Parameter:
封裝並代表了參數實例123456789101112131415
packageLessonForReflection03;importjava.lang.reflect.Constructor;importjava.lang.reflect.Modifier;importjava.lang.reflect.Parameter;/*
*java.lang.reflect.Constructor
*
*Constructor[]getConstructor();獲得本類里的public許可權修飾符構造函數,不能獲取父類的
*Constructor[]getDeclaredConstructor();得本類里的全部構造
*
*Constructor<T>getConstructor(Class...parameterType);用參數決定獲得哪個構造方法
*Constructor<T>getDeclaredConstructor(Class...parameterType);
*
*/{
publicstaticvoidmain(String[]args)
{
System.out.println("獲得Cricle本類里的public許可權修飾符構造函數,不能獲取父類的Constructor[]getConstructor()");
System.out.println("子類繼承不了父類中的構造方法和private");
//Constructor[]getConstructor()獲得Cricle本類里的public許可權修飾符構造函數,不能獲取父類的
//子類繼承不了父類中的構造方法和private
Class<Circle>c1=Circle.class;
Constructor<?>[]cons1=c1.getConstructors();
for(Constructor<?>cons:cons1)
{
System.out.println(cons);
//System.out.println(cons.getName());
}

System.out.println("-----------------------");

System.out.println("方法獲得本類中的所有構造函數getDeclaredConstructor()");
Constructor<?>[]cons2=c1.getDeclaredConstructors();
for(Constructor<?>cons:cons2)
{
System.out.println(cons);
}

System.out.println("-----------------------");

try
{
System.out.println("方法用參數指定獲得本類!構造方法,只能獲取public的Constructor<T>getConstructor(Class...parameterType)");
Constructor<?>cons3=c1.getConstructor(int.class);
System.out.println(Modifier.toString(cons3.getModifiers()));
System.out.println(cons3);

System.out.println("-----------------------");

System.out.println("方法用參數指定獲得本類!構造方法任何許可權修飾符的都可以獲得Constructor<T>getDeclaredConstructor(Class...parameterType)");
Constructor<?>cons4=c1.getDeclaredConstructor(String.class);
System.out.println(cons4);

System.out.println("-----------------------");

/*
*JDK8.0之後新增的類
*Executable:
*是Method和Constructor的父類
*方法:
*getParameter();
*getExceptionTypes();
*getModifiers();
*getTypeParameters();
*
*Parameter:
*封裝並代表了參數實例
*/
System.out.println("獲取類中方法的參數getParameters()");
Constructor<?>cons5=c1.getDeclaredConstructor(int.class,String.class);
Parameter[]p1=cons5.getParameters();
for(Parameterp:p1)
{
System.out.println(p);
}
}catch(NoSuchMethodException|SecurityExceptione)
{
e.printStackTrace();
}

}}5767778798081828384858687

代碼中提到的Circle類和Shape類二者為繼承關系:

packageLessonForReflection03;publicclassCircleextendsShape{
privateintr;
privateStringcolor;

publicCircle(intr,Stringcolor)
{
super();
this.r=r;
this.color=color;
}

publicCircle(intr)
{
super();
this.r=r;
}

protectedCircle(Stringcolor)
{
super();
this.color=color;
}

Circle()
{
super();
}}
packageLessonForReflection03;publicclassShape{
privateintper;

publicShape(intper)
{
super();
this.per=per;
}

publicShape()
{
super();
}}1234567891011121314151617

部分文字來源於:
咕嘟咖啡楊海濱老師 — 《java編程語言高級特性》
輕量化研習Java相關技術倡導者
「愛碼學院」聯合創始人自適應教學理念提出者踐行者;多年開發及項目管理經歷;出版《JavaEE企業級應用與開發》一書;10餘年高校項目實踐畢設指導經驗;企業軟培經驗豐富

『貳』 大神解釋一下java反射有什麼作用

java的反射機制就是增加程序的靈活性,避免將程序寫死到代碼里,

例如: 實例化一個 person()對象, 不使用反射, new person(); 如果想變成 實例化 其他類, 那麼必須修改源代碼,並重新編譯
使用反射: class.forName("person").newInstance(); 而且這個類描述可以寫到配置文件中,如 *.xml, 這樣如果想實例化其他類,只要修改配置文件的"類描述"就可以了,不需要重新修改代碼並編譯。

像spring,struts等這些開源框架的實現都用到了反射機制。

『叄』 java中反射的三種方法是

第一種:通過forName()方法;

第二種:類.class;

第三種:對象.getClass()。

舉例如下:

package
test;

public class Demo{

public static void
main(){

Class<?> c1 = null;

Class<?> c2 =
null;

Class<?> c3 =
null;

//三種反射用實例化方式

try{

//最常用的一種形式

c1 =
Class.forName("test.X");

}catch(ClassNotFoundException
e){

e.printStackTrace();

}

//通過Object類中的方法實例化

c2
= new X().getClass();

//通過類.class實例化

c3 =
X.class;

System.out.println("類名:" + c1.getName());
//得到類名

System.out.println("類名:" + c2.getName());
//得到類名

System.out.println("類名:" + c3.getName());
//得到類名

}

}

『肆』 能說一下java的反射機制嗎

反射:一個類有多個組成部分,例如:成員變數、方法、構造方法等

反射就是載入類,並解剖出類的各個組成部分


java中有一個Class類用於代表某一個類的位元組碼。Class類提供載入某個位元組碼的方法:forName()

forName方法用於載入某個類的位元組碼到內存中,並使用Class對象進行封裝


另外兩種得到Class對象的方式:

  1. 類名.class

  2. 對象。getClass()


SUN公司為簡化創建對象的方法,它在Class對象中也提供了一個newInstance方法,用於創建類的對象,這樣開發人員可以避免每次都需要去反射Constructor類以創建對象

不過需要注意的是,Class.newInstance方法內部是反射類無參的構造函數創建的對象,所以利用此種方式創建類對象時,類必須有一個無參的構造函數


總結如下:反射機制是開發框架時才運用到的技術

『伍』 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 Reflection (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有個更加深入的了解還是應該掌握的。

1.檢測類:

reflection的工作機制

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

import java.lang.reflect.*;

public class DumpMethods {

public static void main(String args[]) {

try {

Class c = Class.forName(args[0]);

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) {

Rectangle r = new Rectangle(100, 325);

printHeight(r);

}

static void printHeight(Rectangle r) {

Field heightField;

Integer heightValue;

Class c = r.getClass();

try {

heightField = c.getField("height");

heightValue = (Integer) heightField.get(r);

System.out.println("Height: " + heightValue.toString());

} catch (NoSuchFieldException e) {

System.out.println(e);

} catch (SecurityException e) {

System.out.println(e);

} catch (IllegalAccessException e) {

System.out.println(e);

}

}

}

安全性和反射:

在處理反射時安全性是一個較復雜的問題。反射經常由框架型代碼使用,由於這一點,我們可能希望框架能夠全面接入代碼,無需考慮常規的接入限制。但是,在其它情況下,不受控制的接入會帶來嚴重的安全性風險,例如當代碼在不值得信任的代碼共享的環境中運行時。

由於這些互相矛盾的需求,Java編程語言定義一種多級別方法來處理反射的安全性。基本模式是對反射實施與應用於源代碼接入相同的限制:

從任意位置到類公共組件的接入

類自身外部無任何到私有組件的接入

受保護和打包(預設接入)組件的有限接入

不過至少有些時候,圍繞這些限制還有一種簡單的方法。我們可以在我們所寫的類中,擴展一個普通的基本類 java.lang.reflect.AccessibleObject 類。這個類定義了一種setAccessible方法,使我們能夠啟動或關閉對這些類中其中一個類的實例的接入檢測。唯一的問題在於如果使用了安全性管理 器,它將檢測正在關閉接入檢測的代碼是否許可了這樣做。如果未許可,安全性管理器拋出一個例外。

下面是一段程序,在TwoString 類的一個實例上使用反射來顯示安全性正在運行:

public class ReflectSecurity {

public static void main(String[] args) {

try {

TwoString ts = new TwoString("a", "b");

Field field = clas.getDeclaredField("m_s1");

// field.setAccessible(true);

System.out.println("Retrieved value is " +

field.get(inst));

} catch (Exception ex) {

ex.printStackTrace(System.out);

}

}

}

如果我們編譯這一程序時,不使用任何特定參數直接從命令行運行,它將在field .get(inst)調用中拋出一個IllegalAccessException異常。如果我們不注釋 field.setAccessible(true)代碼行,那麼重新編譯並重新運行該代碼,它將編譯成功。最後,如果我們在命令行添加了JVM參數 -Djava.security.manager以實現安全性管理器,它仍然將不能通過編譯,除非我們定義了ReflectSecurity類的許可權 限。

反射性能:(轉錄別人的啊)

反射是一種強大的工具,但也存在一些不足。一個主要的缺點是對性能有影響。使用反射基本上是一種解釋操作,我們可以告訴JVM,我們希望做什麼並且它滿足我們的要求。這類操作總是慢於只直接執行相同的操作。

下面的程序是欄位接入性能測試的一個例子,包括基本的測試方法。每種方法測試欄位接入的一種形式 -- accessSame 與同一對象的成員欄位協作,accessOther 使用可直接接入的另一對象的欄位,accessReflection 使用可通過反射接入的另一對象的欄位。在每種情況下,方法執行相同的計算 -- 循環中簡單的加/乘順序。

程序如下:

public int accessSame(int loops) {

m_value = 0;

for (int index = 0; index < loops; index++) {

m_value = (m_value + ADDITIVE_VALUE) *

MULTIPLIER_VALUE;

}

return m_value;

}

public int acces

sReference(int loops) {

TimingClass timing = new TimingClass();

for (int index = 0; index < loops; index++) {

timing.m_value = (timing.m_value + ADDITIVE_VALUE) *

MULTIPLIER_VALUE;

}

return timing.m_value;

}

public int accessReflection(int loops) throws Exception {

TimingClass timing = new TimingClass();

try {

Field field = TimingClass.class.

getDeclaredField("m_value");

for (int index = 0; index < loops; index++) {

int value = (field.getInt(timing) +

ADDITIVE_VALUE) * MULTIPLIER_VALUE;

field.setInt(timing, value);

}

return timing.m_value;

} catch (Exception ex) {

System.out.println("Error using reflection");

throw ex;

}

}

在上面的例子中,測試程序重復調用每種方法,使用一個大循環數,從而平均多次調用的時間衡量結果。平均值中不包括每種方法第一次調用的時間,因此初始化時間不是結果中的一個因素。下面的圖清楚的向我們展示了每種方法欄位接入的時間:

圖 1:欄位接入時間 :

我們可以看出:在前兩副圖中(Sun JVM),使用反射的執行時間超過使用直接接入的1000倍以上。通過比較,IBM JVM可能稍好一些,但反射方法仍舊需要比其它方法長700倍以上的時間。任何JVM上其它兩種方法之間時間方面無任何顯著差異,但IBM JVM幾乎比Sun JVM快一倍。最有可能的是這種差異反映了Sun Hot Spot JVM的專業優化,它在簡單基準方面表現得很糟糕。反射性能是Sun開發1.4 JVM時關注的一個方面,它在反射方法調用結果中顯示。在這類操作的性能方面,Sun 1.4.1 JVM顯示了比1.3.1版本很大的改進。

如果為為創建使用反射的對象編寫了類似的計時測試程序,我們會發現這種情況下的差異不象欄位和方法調用情況下那麼顯著。使用newInstance()調 用創建一個簡單的java.lang.Object實例耗用的時間大約是在Sun 1.3.1 JVM上使用new Object()的12倍,是在IBM 1.4.0 JVM的四倍,只是Sun 1.4.1 JVM上的兩部。使用Array.newInstance(type, size)創建一個數組耗用的時間是任何測試的JVM上使用new type[size]的兩倍,隨著數組大小的增加,差異逐步縮小。隨著jdk6.0的推出,反射機制的性能也有了很大的提升。期待中….

總結:

Java語言反射提供一種動態鏈接程序組件的多功能方法。它允許程序創建和控制任何類的對象(根據安全性限制),無需提前硬編碼目標類。這些特性使得反射 特別適用於創建以非常普通的方式與對象協作的庫。例如,反射經常在持續存儲對象為資料庫、XML或其它外部格式的框架中使用。Java reflection 非常有用,它使類和數據結構能按名稱動態檢索相關信息,並允許在運行著的程序中操作這些信息。Java 的這一特性非常強大,並且是其它一些常用語言,如 C、C++、Fortran 或者 Pascal 等都不具備的。

但反射有兩個缺點。第一個是性能問題。用於欄位和方法接入時反射要遠慢於直接代碼。性能問題的程度取決於程序中是如何使用反射的。如果它作為程序運行中相 對很少涉及的部分,緩慢的性能將不會是一個問題。即使測試中最壞情況下的計時圖顯示的反射操作只耗用幾微秒。僅反射在性能關鍵的應用的核心邏輯中使用時性 能問題才變得至關重要。

許多應用中更嚴重的一個缺點是使用反射會模糊程序內部實際要發生的事情。程序人員希望在源代碼中看到程序的邏輯,反射等繞過了源代碼的技術會帶來維護問 題。反射代碼比相應的直接代碼更復雜,正如性能比較的代碼實例中看到的一樣。解決這些問題的最佳方案是保守地使用反射——僅在它可以真正增加靈活性的地方 ——記錄其在目標類中的使用。

一下是對應各個部分的例子:

具體的應用:

1、 模仿instanceof 運算符號

class A {}

public class instance1 {

public static void main(String args[])

{

try {

Class cls = Class.forName("A");

boolean b1

= cls.isInstance(new Integer(37));

System.out.println(b1);

boolean b2 = cls.isInstance(new A());

System.out.println(b2);

}

catch (Throwable e) {

System.err.println(e);

}

}

}

2、 在類中尋找指定的方法,同時獲取該方法的參數列表,例外和返回值

import java.lang.reflect.*;

public class method1 {

private int f1(

Object p, int x) throws NullPointerException

{

if (p == null)

throw new NullPointerException();

return x;

}

public static void main(String args[])

{

try {

Class cls = Class.forName("method1");

Method methlist[]

= cls.getDeclaredMethods();

for (int i = 0; i < methlist.length;

i++)

Method m = methlist[i];

System.out.println("name

= " + m.getName());

System.out.println("decl class = " +

m.getDeclaringClass());

Class pvec[] = m.getParameterTypes();

for (int j = 0; j < pvec.length; j++)

System.out.println("

param #" + j + " " + pvec[j]);

Class evec[] = m.getExceptionTypes();

for (int j = 0; j < evec.length; j++)

System.out.println("exc #" + j

+ " " + evec[j]);

System.out.println("return type = " +

m.getReturnType());

System.out.println("-----");

}

}

catch (Throwable e) {

System.err.println(e);

}

}

}

3、 獲取類的構造函數信息,基本上與獲取方法的方式相同

import java.lang.reflect.*;

public class constructor1 {

public constructor1()

{

}

protected constructor1(int i, double d)

{

}

public static void main(String args[])

{

try {

Class cls = Class.forName("constructor1");

Constructor ctorlist[]

= cls.getDeclaredConstructors();

for (int i = 0; i < ctorlist.length; i++) {

Constructor ct = ctorlist[i];

System.out.println("name

= " + ct.getName());

System.out.println("decl class = " +

ct.getDeclaringClass());

Class pvec[] = ct.getParameterTypes();

for (int j = 0; j < pvec.length; j++)

System.out.println("param #"

+ j + " " + pvec[j]);

Class evec[] = ct.getExceptionTypes();

for (int j = 0; j < evec.length; j++)

System.out.println(

"exc #" + j + " " + evec[j]);

System.out.println("-----");

}

}

catch (Throwable e) {

System.err.println(e);

}

}

}

4、 獲取類中的各個數據成員對象,包括名稱。類型和訪問修飾符號

import java.lang.reflect.*;

public class field1 {

private double d;

public static final int i = 37;

String s = "testing";

public static void main(String args[])

{

try {

Class cls = Class.forName("field1");

Field fieldlist[]

= cls.getDeclaredFields();

for (int i

= 0; i < fieldlist.length; i++) {

Field fld = fieldlist[i];

System.out.println("name

= " + fld.getName());

System.out.println("decl class = " +

fld.getDeclaringClass());

System.out.println("type

= " + fld.getType());

int mod = fld.getModifiers();

System.out.println("modifiers = " +

Modifier.toString(mod));

System.out.println("-----");

}

}

catch (Throwable e) {

System.err.println(e);

}

}

}

5、 通過使用方法的名字調用方法

import java.lang.reflect.*;

public class method2 {

public int add(int a, int b)

{

return a + b;

}

public static void main(String args[])

{

try {

Class cls = Class.forName("method2");

Class partypes[] = new Class[2];

partypes[0] = Integer.TYPE;

partypes[1] = Integer.TYPE;

Method meth = cls.getMethod(

"add", partypes);

method2 methobj = new method2();

Object arglist[] = new Object[2];

arglist[0] = new Integer(37);

arglist[1] = new Integer(47);

Object retobj

= meth.invoke(methobj, arglist);

Integer retval = (Integer)retobj;

System.out.println(retval.intValue());

}

catch (Throwable e) {

System.err.println(e);

}

}

}

6、 創建新的對象

import java.lang.reflect.*;

public class constructor2 {

public constructor2()

{

}

public constructor2(int a, int b)

{

System.out.println(

"a = " + a + " b = " + b);

}

public static void main(String args[])

{

try {

Class cls = Class.forName("constructor2");

Class partypes[] = new Class[2];

partypes[0] = Integer.TYPE;

partypes[1] = Integer.TYPE;

Constructor ct

= cls.getConstructor(partypes);

Object arglist[] = new Object[2];

arglist[0] = new Integer(37);

arglist[1] = new Integer(47);

Object retobj = ct.newInstance(arglist);

}

catch (Throwable e) {

System.err.println(e);

}

}

}

7、 變更類實例中的數據的值

import java.lang.reflect.*;

public class field2 {

public double d;

public static void main(String args[])

{

try {

Class cls = Class.forName("field2");

Field fld = cls.getField("d");

field2 f2obj = new field2();

System.out.println("d = " + f2obj.d);

fld.setDouble(f2obj, 12.34);

System.out.println("d = " + f2obj.d);

}

catch (Throwable e) {

System.err.println(e);

}

}

}

使用反射創建可重用代碼:

1、 對象工廠

Object factory(String p) {

Class c;

Object o=null;

try {

c = Class.forName(p);// get class def

o = c.newInstance(); // make a new one

} catch (Exception e) {

System.err.println("Can't make a " + p);

}

return o;

}

public class ObjectFoundry {

public static Object factory(String p)

throws ClassNotFoundException,

InstantiationException,

IllegalAccessException {

Class c = Class.forName(p);

Object o = c.newInstance();

return o;

}

}

2、 動態檢測對象的身份,替代instanceof

public static boolean

isKindOf(Object obj, String type)

throws ClassNotFoundException {

// get the class def for obj and type

Class c = obj.getClass();

Class tClass = Class.forName(type);

while ( c!=null ) {

if ( c==tClass ) return true;

c = c.getSuperclass();

}

return false;

}

『柒』 Java反射為什麼需要無參構造函數

,因為反射可以理解為Java中的解剖學,首先得先獲取到Class對象,然後才可以分別獲取到類中的內容(構造方法、成員變數和成員方法等),你要獲皮咐取對象,那絕慎就是要定義燃宏純的對象,所以就需要空參構造...

『捌』 JAVA中反射是什麼

JAVA中反射是動態獲取信息以及動態調用對象方法的一種反射機制。

Java反射就是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意方法和屬性;並且能改變它的屬性。而這也是Java被視為動態語言的一個關鍵性質。

Java反射的功能是在運行時判斷任意一個對象所屬的類,在運行時構造任意一個類的對象,在運行時判斷任意一個類所具有的成員變數和方法,在運行時調用任意一個對象的方法,生成動態代理。

(8)java反射構造函數擴展閱讀:

JAVA中反射實例:

1、Class superClass=clazz.getSuperclass();//獲取父類。

System.out.println("getSuperclass:"+superClass)。

2、Class[] interfaces=clazz.getInterfaces();//獲取實現介面。

System.out.println("getInterfaces:"+interfaces.length)。

3、Constructor[] cons=clazz.getConstructors();//構造方法。

System.out.println("getConstructors:"+cons.length)。

參考資料來源:網路: JAVA反射機制

閱讀全文

與java反射構造函數相關的資料

熱點內容
幼兒編程教育培訓多少錢 瀏覽:401
經常生氣有什麼東西能解壓 瀏覽:900
代理伺服器地址和埠可以怎麼填 瀏覽:62
unity5手游編譯模型 瀏覽:265
安卓無人機app源碼 瀏覽:808
pl1編程語言 瀏覽:801
台達plc編程換算指令大全 瀏覽:174
手機上的編程游戲 瀏覽:108
伺服器密碼機有什麼用 瀏覽:477
dos磁碟命令 瀏覽:955
單片機cpu52的功能 瀏覽:691
opc伺服器怎麼開發 瀏覽:373
覓喜是個什麼app 瀏覽:402
加密cd機 瀏覽:946
社保用什麼app繳納 瀏覽:313
nodevlinux 瀏覽:582
騰訊tt伺服器怎麼登錄密碼 瀏覽:898
windows命令提示符 瀏覽:352
win7管理員許可權命令 瀏覽:729
地圖app哪個適合老年人用 瀏覽:74