Ⅰ java 反射有什麼用
反射就是把java類中的各種成分映射成為相應的java類。例如:一個java類用一個Class類的對象來表示,一個類中的組成部分:成員變數、方法、構造函數、包等等信息也用一個個java類來表示,就像汽車是一個類,汽車中的發動機,變速箱等等也是一個個的java類,表示java類的Class類顯然要提供一系列的方法,來獲得其中的變數,方法,構造函數,修飾符,包等信息,這些信息就是用相應類的實例對象來表示,它們是Field、Method、Constructor、Package等等
在平時的編程中,反射基本用不到,但是在編寫框架的時候,反射用的就多了,比如你要使用某一個類進行操作,但是這個類是用戶通過配置文件配置進來的,你需要先讀配置文件,然後拿到這個類的全類名:比如com.onede4..Person,然後在利用反射API來做操作
Ⅱ 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裡面反射的原理是什麼
java虛擬機運行時內存有個叫方法區,主要作用是存儲被裝載的類的類型信息。每裝載一個類的時候,java就會創建一個該類的Class對象實例。我們就可以通過這個實例,來訪問這個類的信息。
Ⅳ Java反射 在只知道類名的情況下,怎樣給其中的私有屬性賦值
利用反射能
//假設類名為A
//實例化類
Ap=newA();
//獲取class
Classc=p.getClass();
//獲取該類所有的欄位
Field[]fields=c.getDeclaredFields();
//遍歷賦值
for(inti=0;i<fields.length;i++){
StringfiledName=fields[i].getName();
//AccessibleTest類中的成員變數為private,故必須進行此操作
fields[i].setAccessible(true);
//判斷類型
Class<?>type=fields[i].getType();
//獲取欄位類型
StringtypeName=type.getName();
System.out.println(type.getName());
//對欄位進行賦值第一個參數為對象引用第二個參數為要附的值
//如果為字元串類型
if("java.lang.String".equals(typeName)){
fields[i].set(p,"1");
}
//如果為日期類型
elseif("java.util.Date".equals(typeName)){
fields[i].set(p,newDate());
}
else{
fields[i].set(p,1);
}
}
//樓主我只是簡單的寫了下。可能還需要判斷欄位名稱以及其他類型什麼的。
最後希望樓主多看看java 文檔。
Ⅳ Java的反射到底有什麼用途
JDK動態代理生成代理類的位元組碼後,首先把這個類通過defineclass定義成一個類,然後用class.for(name)會把該類載入到jvm,之後我們就可以通過,A.class.GetMethod()獲取其方法,然後通過invoke調用其方法,在調用這個方法時,實際上會通過被代理類的引用再去調用原方法。
Java反射包reflection提供對Class,Method,field,constructor1 等信息的封裝類型
通過這些api可以輕易獲得一個類的各種信息並且可以進行實例化,方法調用等。
類中的private參數可以通過setaccessible方法強制獲取。
Ⅵ java中反射實例類裝載的步驟及簡要闡述
java反射和類裝載
反射機制:
Person p=new Person();
這是什麼?當然是實例化一個對象了.可是這種實例化對象的方法存在一個問題,那就是必須要知道類名才可以實例化它的對象,這樣我們在應用方面就會受到限制.那麼有沒有這樣一種方式,讓我們不知道這個類的類名就可以實例化它的對象呢?Thank Goodness!幸虧我們用的是java, java就提供了這樣的機制.
1).java程序在運行時可以獲得任何一個類的位元組碼信息,包括類的修飾符(public,static等),基類(超類,父類),實現的介面,欄位和方法等信息.
2).java程序在運行時可以根據位元組碼信息來創建該類的實例對象,改變對象的欄位內容和調用對象方法.
這樣的機制就叫反射技術.可以想像光學中的反射,就像我們照鏡子,鏡子中又出現一個自己(比喻可能不太恰當,但是足以表達清楚意思了).反射技術提供了一種通用的動態連接程序組件的方法,不必要把程序所需要的目標類硬編碼到源程序中,從而使得我們可以創建靈活的程序.
反射的實現步驟( 不問不需要答) ,
1、獲取類的常用方式有三種: a) Class.forName("包名.類名"),最常用、推薦;b) 包名.類名.class 最簡捷;c) 對象.getClass 的方式獲得。
2、對象的實例化,上面已經獲取了類,只需要調用類的實例化方法,類.newInstance()便可。
3、獲取屬性和構造等,可以參考 JavaApi 的調用,類. getDeclaredFields,類. getConstructor(..)等。
Java的反射機制是通過反射API來實現的,它允許程序在運行過程中取得任何一個已知名稱的類的內部信息.反射API位於java.lang.reflect包中.主要包括以下幾類:
1).Constructor類:用來描述一個類的構造方法
2).Field類:用來描述一個類的成員變數
3).Method類:用來描述一個類的方法.
4).Modifer類:用來描述類內各元素的修飾符
5).Array:用來對數組進行操作.
Constructor,Field,Method這三個類都是JVM(虛擬機)在程序運行時創建的,用來表示載入類中相應的成員.這三個類都實現了java.lang.reflect.Member介面,Member介面定義了獲取類成員或構造方法等信息的方法.要使用這些反射API,必須先得到要操作的對象或類的Class類的實例.通過調用Class類的newInstance方法(只能調用類的默認構造方法)可以創建類的實例.這樣有局限性,我們可以先沖類的Class實例獲取類需要的構造方法,然後在利用反射來創建類的一個實例.
類載入機制:
類的載入機制可以分為載入-鏈接-初始化三個階段,鏈接又可以分為驗證、准備、解析三個過程。
載入:通過類的載入器查找並載入二進制位元組流的過程,在堆內存中的方法區生成 一個代表這個類的 java.lang.Class 對象,作為這個類的數據請求入口。(這里可以把上面類載入器載入文件的過程描述一下(參考版本一,不作重復))。
驗證:主要是對一些詞法、語法進行規范性校驗,避免對 JVM 本身安全造成危害; 比如對文件格式,位元組碼驗證,無數據驗證等。但驗證階段是非必須的,可以通過參數 設置來進行關閉,以提高載入的時效。
准備:對類變數分配內存,並且對類變數預初始化,初始化成數據類型的原始值, 比如 static int a=11,會被初始化成成 a=0;如果是 static double a =11,則會被初始化成 a=0.0; 而成員變數只會成實例化後的堆中初始化。
解析:把常量池中的符號引用轉換為直接引用的過程。
初始化:對類的靜態變數和靜態塊中的變數進行初始化。(上面的准備階段可以作為 預初始化,初始到變數類型的原值,但如果被 final 修飾會進行真正初始化)
上面載入、鏈接、初始化的各個階段並不是彼此獨立,而是交叉進行,這點很重要 。
***class.forName和 classloader的區別
Class.forName 和 ClassLoader 都是用來裝載類的,對於類的裝載一般為分三個階段載入、鏈接、編譯,它們裝載類的方式是有區別。
首先看一下 Class.forName(..),forName(..)方法有一個重載方法 forName(className,boolean,ClassLoader),它有三個參數,第一個參數是類的包路徑,第二個參數是 boolean
類型,為 true 地表示 Loading 時會進行初始化,第三個就是指定一個載入器;當你調用class.forName(..)時,默認調用的是有三個參數的重載方法,第二個參數默認傳入 true,第三個參數默認使用的是當前類載入時用的載入器。
ClassLoader.loadClass()也有一個重載方法,從源碼中可以看出它默認調的是它的重載 方法 loadClass(name, false),當第二參數為 false 時,說明類載入時不會被鏈接。這也是兩者之間最大區別,前者在載入的時候已經初始化,後者在載入的時候還沒有鏈接。如果你需要在載入時初始化一些東西,就要用 Class.forName 了,比如我們常用的驅動載入, 實際上它的注冊動作就是在載入時的一個靜態塊中完成的。所以它不能被 ClassLoader 載入代替。
Ⅶ 利用java反射機制,通過一個對象獲得完整的包名和類名
1、Test t = new Test().Class clazz = t.getClass().System.out.println(clazz.getCanonicalName()).System.out.println(clazz.getSimpleName()).
2、public class TestReflect {public static void main(String[] args) throws Exception {TestReflect testReflect = new TestReflect().System.out.println(testReflect.getClass().getName()).// 結果 net.xsoftlab.ke.TestReflect.}}
3、Java程序
Ⅷ 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反射指的是對於任何的一個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反射工具類
反射的Utils函數集合
提供訪問私有變數 獲取泛型類型Class 提取集合中元素的屬性等Utils函數
package reflection
import java lang reflect Field import java lang reflect Modifier import java lang reflect ParameterizedType import java lang reflect Type import java util ArrayList import java util Collection import java util List
import mons beanutils PropertyUtils import mons lang StringUtils import slf j Logger import slf j LoggerFactory import springframework util Assert
/** * 反射的Utils函數集合 提供訪問私有變數 獲取泛型類型Class 提取集合中元素的屬性等Utils函數
* * @author lei */ public class ReflectionUtils {
private static Logger logger = LoggerFactory getLogger(ReflectionUtils class)
private ReflectionUtils() { }
/** * 直接讀取對象屬性值 無視private/protected修飾符 不經過getter函數
*/ public static Object getFieldValue(final Object object final String fieldName) { Field field = getDeclaredField(object fieldName)
if (field == null)
throw new IllegalArgumentException( Could not find field [ + fieldName + ] on target [ + object + ] )
makeAccessible(field)
Object result = null try { result = field get(object) } catch (IllegalAccessException e) { logger error( 不可能拋出的異常{} e getMessage()) } return result }
/** * 直接設置對象屬性值 無視private/protected修飾符 不經過setter函數
*/ public static void setFieldValue(final Object object final String fieldName final Object value) { Field field = getDeclaredField(object fieldName)
if (field == null)
throw new IllegalArgumentException( Could not find field [ + fieldName + ] on target [ + object + ] )
makeAccessible(field)
try { field set(object value) } catch (IllegalAccessException e) { logger error( 不可能拋出的異常 {} e getMessage()) } }
/** * 循環向上轉型 獲取對象的DeclaredField */ protected static Field getDeclaredField(final Object object final String fieldName) { Assert notNull(object object不能為空 ) return getDeclaredField(object getClass() fieldName) }
/** * 循環向上轉型 獲取類的DeclaredField */ @SuppressWarnings( unchecked )
protected static Field getDeclaredField(final Class clazz final String fieldName) { Assert notNull(clazz clazz不能為空 ) Assert hasText(fieldName fieldName ) for (Class superClass = clazz superClass != Object class superClass = superClass getSuperclass()) { try { return superClass getDeclaredField(fieldName) } catch (NoSuchFieldException e) { // Field不在當前類定義 繼續向上轉型 } } return null }
/** * 強制轉換fileld可訪問
*/ protected static void makeAccessible(final Field field) { if (!Modifier isPublic(field getModifiers()) || !Modifier isPublic(field getDeclaringClass() getModifiers())) { field setAccessible(true) } }
/** * 通過反射 獲得定義Class時聲明的父類的泛型參數的類型 如public UserDao extends HibernateDao<User> * * @param clazz * The class to introspect * @return the first generic declaration or Object class if cannot be * determined */ @SuppressWarnings( unchecked )
public static Class getSuperClassGenricType(final Class clazz) { return getSuperClassGenricType(clazz ) }
/** * 通過反射 獲得定義Class時聲明的父類的泛型參數的類型 如public UserDao extends * HibernateDao<User Long> * * @param clazz * clazz The class to introspect * @param index * the Index of the generic ddeclaration start from * @return the index generic declaration or Object class if cannot be * determined */
@SuppressWarnings( unchecked )
public static Class getSuperClassGenricType(final Class clazz final int index) {
Type genType = clazz getGenericSuperclass()
if (!(genType instanceof ParameterizedType)) { logger warn(clazz getSimpleName() + s superclass not ParameterizedType ) return Object class }
Type[] params = ((ParameterizedType) genType) getActualTypeArguments()
if (index >= params length || index < ) { logger warn( Index + index + Size of + clazz getSimpleName() + s Parameterized Type + params length) return Object class } if (!(params[index] instanceof Class)) { logger warn(clazz getSimpleName() + not set the actual class on superclass generic parameter ) return Object class } return (Class) params[index] }
/** * 提取集合中的對象的屬性 組合成List * * @param collection * 來源集合
* @param propertityName * 要提取的屬性名
*/ @SuppressWarnings( unchecked )
public static List fetchElementPropertyToList(final Collection collection final String propertyName) throws Exception {
List list = new ArrayList()
for (Object obj collection) { list add(PropertyUtils getProperty(obj propertyName)) }
return list }
/** * 提取集合中的對象的屬性 組合成由分割符分隔的字元串
* * @param collection * 來源集合
* @param propertityName * 要提取的屬性名
* @param separator * 分隔符
*/ @SuppressWarnings( unchecked )
lishixin/Article/program/Java/hx/201311/26718