關(guān)于Java反射機(jī)制 你需要知道的事情
大家都知道,要讓Java程序能夠運(yùn)行,那么就得讓Java類要被Java虛擬機(jī)加載。Java類如果不被Java虛擬機(jī)加載,是不能正常運(yùn)行的?,F(xiàn)在我們運(yùn)行的所有的程序都是在編譯期的時(shí)候就已經(jīng)知道了你所需要的那個(gè)類的已經(jīng)被加載了。
Java的反射機(jī)制是在編譯并不確定是哪個(gè)類被加載了,而是在程序運(yùn)行的時(shí)候才加載、探知、自審。使用在編譯期并不知道的類。這樣的特點(diǎn)就是反射。
反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意一個(gè)對象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制。
本篇將從以下幾個(gè)方面講述反射的知識(shí):
calss的使用 方法的反射 構(gòu)造函數(shù)的反射 成員變量的反射
一、什么是class類
在面向?qū)ο蟮氖澜缋?,萬物皆對象。類是對象,類是java.lang.Class類的實(shí)例對象。另外class類只有java虛擬機(jī)才能new出來。任何一個(gè)類都是Class 類的實(shí)例對象。這實(shí)例對象有三種表達(dá)方式:
public class User{
}
public class ClassTest{
User u=new User();
//方式1:
Class c1=User.class;
//方式2:
Class c2=u.getClass();
//方式3:
Class c3=Class.forName("com.forezp.User");
//可以通過類的類型創(chuàng)建該類的實(shí)例對象
User user=(User)c1.newInstance();
}
二、class類的動(dòng)態(tài)加載
Class.forName(類的全稱);該方法不僅表示了類的類型,還代表了動(dòng)態(tài)加載類。編譯時(shí)刻加載類是靜態(tài)加載、運(yùn)行時(shí)刻加載類是動(dòng)態(tài)加載類。
三、獲取方法信息
基本的數(shù)據(jù)類型,void關(guān)鍵字都Class 類的實(shí)例;可以通過get
ame();getSimpleName()獲取類的名稱。
Class c1=String.class; Class c2=int.class; Class c3=void.class; System.out.println(c1.getName()); System.out.println(c2.getSimpleName());
獲取類的所有方法,并打印出來:
public static void printClassInfo(Object object){
Class c=object.getClass();
System.out.println("類的名稱:"+c.getName());
/**
* 一個(gè)成員方法就是一個(gè)method對象
* getMethod()所有的 public方法,包括父類繼承的 public
* getDeclaredMethods()獲取該類所有的方法,包括private ,但不包括繼承的方法。
*/
Method[] methods=c.getMethods();//獲取方法
//獲取所以的方法,包括private ,c.getDeclaredMethods();
for(int i=0;i<methods.length;i++){ parametertypes="methods[i].getParameterTypes();" pre="" returntype="methods[i].getReturnType();"></methods.length;i++){>
public class ReflectTest {
public static void main(String[] args){
String s="ss";
ClassUtil.printClassInfo(s);
}
}
運(yùn)行:
類的名稱:java.lang.String booleanequals(java.lang.Object,) java.lang.StringtoString() inthashCode() …
四、獲取成員變量的信息
也可以獲取類的成員變量信息
public static void printFiledInfo(Object o){
Class c=o.getClass();
/**
* getFileds()獲取public
* getDeclaredFields()獲取所有
*/
Field[] fileds=c.getDeclaredFields();
for(Field f:fileds){
//獲取成員變量的類型
Class filedType=f.getType();
System.out.println(filedType.getName()+" "+f.getName());
}
}
public static void main(String[] args){
String s="ss";
//ClassUtil.printClassInfo(s);
ClassUtil.printFiledInfo(s);
}
運(yùn)行:
[C value int hash long serialVersionUID [Ljava.io.ObjectStreamField; serialPersistentFields java.util.Comparator CASE_INSENSITIVE_ORDER int HASHING_SEED int hash32
五、獲取構(gòu)造函數(shù)的信息
public static void printConstructInfo(Object o){
Class c=o.getClass();
Constructor[] constructors=c.getDeclaredConstructors();
for (Constructor con:constructors){
System.out.print(con.getName()+"(");
Class[] typeParas=con.getParameterTypes();
for (Class class1:typeParas){
System.out.print(class1.getName()+" ,");
}
System.out.println(")");
}
}
public static void main(String[] args){
String s="ss";
//ClassUtil.printClassInfo(s);
//ClassUtil.printFiledInfo(s);
ClassUtil.printConstructInfo(s);
}
運(yùn)行:
java.lang.String([B ,) java.lang.String([B ,int ,int ,) java.lang.String([B ,java.nio.charset.Charset ,) java.lang.String([B ,java.lang.String ,) java.lang.String([B ,int ,int ,java.nio.charset.Charset ,) java.lang.String(int ,int ,[C ,) java.lang.String([C ,boolean ,) java.lang.String(java.lang.StringBuilder ,) java.lang.String(java.lang.StringBuffer ,) …
六、方法反射的操作
獲取一個(gè)方法:需要獲取方法的名稱和方法的參數(shù)才能決定一個(gè)方法。
方法的反射操作:
method.invoke(對象,參數(shù)列表);
舉個(gè)例子:
class A{
public void add(int a,int b){
System.out.print(a+b);
}
public void toUpper(String a){
System.out.print(a.toUpperCase());
}
}
public static void main(String[] args) {
A a=new A();
Class c=a.getClass();
try {
Method method=c.getMethod("add",new Class[]{int.class,int.class});
//也可以 Method method=c.getMethod("add",int.class,int.class);
//方法的反射操作
method.invoke(a,10,10);
}catch (Exception e){
e.printStackTrace();
}
}
運(yùn)行:
20
本篇文章已經(jīng)講解了java反射的基本用法, 它可以在運(yùn)行時(shí)判斷任意一個(gè)對象所屬的類;在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對象;在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法;在運(yùn)行時(shí)調(diào)用任意一個(gè)對象的方法;生成動(dòng)態(tài)代理。
以上就是本文關(guān)于Java反射機(jī)制的全部內(nèi)容,希望對大家有所幫助。
更多相關(guān)內(nèi)容可以參考:Java的RTTI和反射機(jī)制代碼分析、Java反射機(jī)制深入理解、Java 反射機(jī)制實(shí)例詳解。
相關(guān)文章
MyBatis?多表聯(lián)合查詢及優(yōu)化方法
大家都知道Hibernate 是全自動(dòng)的數(shù)據(jù)庫持久層框架,它可以通過實(shí)體來映射數(shù)據(jù)庫,通過設(shè)置一對多、多對一、一對一、多對多的關(guān)聯(lián)來實(shí)現(xiàn)聯(lián)合查詢,接下來通過本文給大家介紹MyBatis?多表聯(lián)合查詢及優(yōu)化,需要的朋友可以參考下2022-08-08
SpringBoot整合EasyExcel實(shí)現(xiàn)大規(guī)模數(shù)據(jù)的并行導(dǎo)出與壓縮下載
在 Spring Boot 應(yīng)用中,整合 EasyExcel 實(shí)現(xiàn)并行導(dǎo)出數(shù)據(jù)并進(jìn)行 Zip 壓縮下載可以極大地提高數(shù)據(jù)處理效率和用戶體驗(yàn),文中通過代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2024-10-10
Java利用TCP實(shí)現(xiàn)服務(wù)端向客戶端消息群發(fā)的示例代碼
這篇文章主要為大家詳細(xì)介紹了Java如何利用TCP協(xié)議實(shí)現(xiàn)服務(wù)端向客戶端消息群發(fā)功能,文中的示例代碼講解詳細(xì),需要的可以參考下,希望對你有所幫助2022-08-08
JAVA基于PDF box將PDF轉(zhuǎn)為圖片的實(shí)現(xiàn)方法
這篇文章主要介紹了JAVA基于PDF box將PDF轉(zhuǎn)為圖片的操作方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-07-07
Java利用策略模式實(shí)現(xiàn)條件判斷,告別if else
策略模式定義了一系列算法,并且將每個(gè)算法封裝起來,使得他們可以相互替換,而且算法的變化不會(huì)影響使用算法的客戶端。本文將通過案例講解如何利用Java的策略模式實(shí)現(xiàn)條件判斷,告別if----else條件硬編碼,需要的可以參考一下2022-02-02
mybatis定義sql語句標(biāo)簽之delete標(biāo)簽解析
這篇文章主要介紹了mybatis定義sql語句標(biāo)簽之delete標(biāo)簽解析,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03

