Java反射機制的完成詳解。本站提示廣大學習愛好者:(Java反射機制的完成詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是Java反射機制的完成詳解正文
許多主流框架都應用了反射技巧.像ssh框架都采取兩種技巧 xml做設置裝備擺設文件+反射技巧.
與反射有關的類包.
java.lang.reflect.*;和java.lang.Class;
Java中一切類型(包含根本類型)都對應一個Class對象,這個Class就是java.lang.Class。即每個類型,在Class中都有一個Class對象跟它對應.Class 沒有公共結構辦法。留意不是沒有,是沒有公共的.
若何取得Class對象
.針對每個對象.getCalss(),可以獲得對應的Class.
.Class.forName(String),String的寫法:包名.類名.就會創立包名.類名對應的誰人對象
注:1.2只實用於援用類型
.關於根本類型:封裝類.TYPE代表了對應的根本類型的Class對象.Integer.TYPE對應的是int的Class對象
注:3只實用於根本類型
.類型,Class。<第4種是通用的.>
下面的4種辦法,只要辦法2是靜態的,只需換一個包便可以了.它具有靜態潛質.所以真正意義的想表現靜態編程只能應用辦法2.
每品種型的Class對象只要一個,即他們的地址只要一個,然則分歧類型是分歧的.
所以上面的打印成果都為true.
//對與援用類型
Class c1 = "".getClass();
Class c2 = Class.forName("java.lang.String");
Class c3 = String.class;
System.out.println(c1 ==c2);//true
//關於根本類型
Class num1 = Integer.TYPE;
Class num2 = int.class;
System.out.println(num1 == num2);//true
反射獲得類中的成員的相干辦法
[獲得結構<依據參數類型>](應用時普通用不帶declared的)
Constructor<T> getConstructor(Class<?>... parameterTypes)
前往一個 Constructor 對象,它反應此 Class 對象所表現的類的指定公共結構辦法。
Constructor<?>[] getConstructors()
前往一個包括某些 Constructor 對象的數組,這些對象反應此 Class 對象所表現的類的一切公共結構辦法。
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
前往一個 Constructor 對象,該對象反應此 Class 對象所表現的類或接口的指定結構辦法。
Constructor<?>[] getDeclaredConstructors()
前往 Constructor 對象的一個數組,這些對象反應此 Class 對象表現的類聲明的一切結構辦法。
[獲得屬性<依據屬性名>](應用時普通用是帶declared的,由於屬性普通都是公有的)
Field getField(String name)
前往一個 Field 對象,它反應此 Class 對象所表現的類或接口的指定公共成員字段。
Field[] getFields()
前往一個包括某些 Field 對象的數組,這些對象反應此 Class 對象所表現的類或接口的一切可拜訪公共字段。
Field getDeclaredField(String name)
前往一個 Field 對象,該對象反應此 Class 對象所表現的類或接口的指定已聲明字段。
Field[] getDeclaredFields()
前往 Field 對象的一個數組,這些對象反應此 Class 對象所表現的類或接口所聲明的一切字段。
[獲得辦法<辦法名加上參數類型>](應用時普通用不帶declared的)
Method getMethod(String name, Class<?>... parameterTypes)
前往一個 Method 對象,它反應此 Class 對象所表現的類或接口的指定公共成員辦法。
Method[] getMethods()
前往一個包括某些 Method 對象的數組,這些對象反應此 Class 對象所表現的類或接口(包含那些由該類或接口聲明的和從超類和超接口繼續的那些的類或接口)的公共 member 辦法。
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
前往一個 Method 對象,該對象反應此 Class 對象所表現的類或接口的指定已聲明辦法。
Method[] getDeclaredMethods()
前往 Method 對象的一個數組,這些對象反應此 Class 對象表現的類或接口聲明的一切辦法,包含公共、掩護、默許(包)拜訪和公有辦法,但不包含繼續的辦法。
T newInstance()
創立此 Class 對象所表現的類的一個新實例。 <new Instance()可以靜態的創立對象>
String toString()
將對象轉換為字符串。
留意:
new Instance()挪用的是無參結構,假如該類沒有沒有參結構辦法,則newInstance()會發生異常.
有declared的辦法是支撐公有,然則不支撐繼續,無declared的辦法支撐繼續,不支撐公有,且只能掏出public的器械.
是以取屬性的時刻普通來講是帶declared的,由於屬性普通都是公有的,取辦法時普通是不帶declared的,取結構時普通也是不帶declared的.
實例模仿反射獲得類中的相干屬性和辦法
應用反射對屬性賦值
Field中的辦法
Object get(Object obj)
前往指定對象上此 Field 表現的字段的值。
Field f = c.getXXField(屬性名);
值 = f.get(對象);
void set(Object obj, Object value)
將指定對象變量上此 Field 對象表現的字段設置為指定的新值。
f.set(對象,值);
Class<?> getType()
前往一個 Class 對象,它標識了此 Field 對象所表現字段的聲明類型。
用於獲得屬性的類型(前往Class對象).
Class c = Student.class;
Object obj = c.newInstance(); //創立Student類的對象
Field f = c.getDeclaredField("name"); //獲得name屬性
f.setAccessible(true); //設置公有可以拜訪.
f.set(obj, "zhangsan");
System.out.println(f.get(obj)); //獲得obj的name屬性的值.
應用反射挪用結構
關於結構真正挪用是在挪用newInstance()辦法時.
Class c = Class.forName("com.clazz.reflect.Student");
Constructor con = c.getConstructor(); //沒有履行結構,
Object cObj = c.getConstructor().newInstance();//挪用無參的結構辦法
Constructor conAll = c.getConstructor(int.class,String.class,int.class);
Object caobj = conAll.newInstance(1001,"zjamgs",234235);//挪用含參的結構辦法.
System.out.println(caobj); //打印輸入
應用反射挪用辦法
對象.辦法名(值1,2,3);
Method m = c.getMethoed(辦法名,參數類型...);
m.invoke(對象,辦法挪用的參數 )假如底層辦法所需的形參數為 0,則所供給的 args 數組長度可認為 0 或 null。
Class c = Class.forName("com.clazz.reflect.Student");
Object obj = c.newInstance(); //創立Sutdent對象.
Method msetName = c.getMethod("setName", String.class);//obj不必轉換類型
msetName.invoke(obj, "zhangsan");//挪用辦法setName, 並傳參.
Method msetId = c.getMethod("setId", int.class);
msetId.invoke(obj, 409090202);
System.out.println(obj);
反射運用實例
實體類
package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
*
* User.java
*
* @version : 1.1
*
* @author : 蘇若年 <a href="mailto:[email protected]">發送郵件</a>
*
* @since : 1.0 創立時光: 2013-2-26 下晝01:43:56
*
* TODO : class User.java is used for ...
*
*/
public class User implements Serializable{
private String test;
public void execute(String name,int age){
System.out.println("name=" + name + ",age=" + age);
}
}
反射測試類
package org.dennisit.reflect.main;
import java.lang.reflect.Field;
/**
*
* ReflectEx.java
*
* @version : 1.1
*
* @author : 蘇若年 <a href="mailto:[email protected]">發送郵件</a>
*
* @since : 1.0 創立時光: 2013-2-26 下晝01:46:00
*
* TODO : class ReflectEx.java is used for ...
*
*/
public class ReflectEx {
public static void main(String[] args)throws Exception {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
Object obj = cls.newInstance(); //創立User的對象
Field f = cls.getDeclaredField("test"); //獲得test屬性
f.setAccessible(true); //翻開公有屬性test的拜訪權限
f.set(obj, "zhangsan"); //為test從新復制
System.out.println(f.get(obj)); //獲得obj的test屬性值
//依據辦法名execute獲得辦法
java.lang.reflect.Method m = cls.getMethod("execute", String.class, int.class);
m.invoke(obj, "dennisit",23); //挪用execute辦法
}
}
運轉後果
zhangsan
name=dennisit,age=23
編寫一個反射靜態實例化類的例子
package org.dennisit.reflect.main;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;
/**
*
* DynamicReflect.java
*
* @version : 1.1
*
* @author : 蘇若年 <a href="mailto:[email protected]">發送郵件</a>
*
* @since : 1.0 創立時光: 2013-2-26 下晝01:58:12
*
* TODO : 應用反射靜態實例化的例子
*
*/
public class DynamicReflect {
public static Object getInstance(String className,Map<String,Object> map)throws Exception{
Class c = Class.forName(className);
Object obj = c.newInstance(); //對象對象
Set<String> keys = map.keySet(); //獲得對應的一切屬性
Field[] fAll = c.getDeclaredFields(); //獲得類中一切屬性
for(int i=0;i<fAll.length;i++){
for(String key:keys){ //輪回婚配
if(fAll[i].getName().equals(key)){ //假如用戶傳入的屬性跟獲得到的類中的屬性名婚配
Field f = c.getDeclaredField(key);//獲得該屬性
//構建setXxx()辦法名
String methodName = "set" + key.substring(0,1).toUpperCase()+key.substring(1);
Method method = c.getMethod(methodName, f.getType());//依據構建的用戶名獲得對應的辦法
method.invoke(obj, map.get(key));//辦法挪用
}else{
continue;
}
}
}
return obj;
}
}
接上去我們測試我們編寫的靜態反射實例化例子
實體類
package org.dennisit.reflect.entity;
import java.io.Serializable;
/**
*
* User.java
*
* @version : 1.1
*
* @author : 蘇若年 <a href="mailto:[email protected]">發送郵件</a>
*
* @since : 1.0 創立時光: 2013-2-26 下晝01:43:56
*
* TODO : 實體類
*
*/
public class User implements Serializable{
private String name;
private int age;
private String email;
public User() { //必需有沒有參結構
}
//getter() and setter()
}
主測試類
package org.dennisit.reflect.main;
import java.util.HashMap;
import java.util.Map;
import org.dennisit.reflect.entity.User;
/**
*
* ReflectEx.java
*
* @version : 1.1
*
* @author : 蘇若年 <a href="mailto:[email protected]">發送郵件</a>
*
* @since : 1.0 創立時光: 2013-2-26 下晝01:46:00
*
* TODO : class ReflectEx.java is used for ...
*
*/
public class ReflectEx {
public static void main(String[] args)throws Exception {
Class cls = Class.forName("org.dennisit.reflect.entity.User");
String className = "org.dennisit.reflect.entity.User";
Map<String,Object> map = new HashMap<String, Object>();
map.put("name", "dennisit");
map.put("age", 22);
map.put("email", "[email protected]");
User user = (User)DynamicReflect.getInstance(className, map);
System.out.println(user.getName() + "," + user.getAge() + "," + user.getEmail());
}
}
法式運轉成果
dennisit,22,[email protected]