關(guān)于Java反射機(jī)制 你需要知道的事情
大家都知道,要讓Java程序能夠運(yùn)行,那么就得讓Java類(lèi)要被Java虛擬機(jī)加載。Java類(lèi)如果不被Java虛擬機(jī)加載,是不能正常運(yùn)行的?,F(xiàn)在我們運(yùn)行的所有的程序都是在編譯期的時(shí)候就已經(jīng)知道了你所需要的那個(gè)類(lèi)的已經(jīng)被加載了。
Java的反射機(jī)制是在編譯并不確定是哪個(gè)類(lèi)被加載了,而是在程序運(yùn)行的時(shí)候才加載、探知、自審。使用在編譯期并不知道的類(lèi)。這樣的特點(diǎn)就是反射。
反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱(chēng)為java語(yǔ)言的反射機(jī)制。
本篇將從以下幾個(gè)方面講述反射的知識(shí):
calss的使用 方法的反射 構(gòu)造函數(shù)的反射 成員變量的反射
一、什么是class類(lèi)
在面向?qū)ο蟮氖澜缋铮f(wàn)物皆對(duì)象。類(lèi)是對(duì)象,類(lèi)是java.lang.Class類(lèi)的實(shí)例對(duì)象。另外class類(lèi)只有java虛擬機(jī)才能new出來(lái)。任何一個(gè)類(lèi)都是Class 類(lèi)的實(shí)例對(duì)象。這實(shí)例對(duì)象有三種表達(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");
//可以通過(guò)類(lèi)的類(lèi)型創(chuàng)建該類(lèi)的實(shí)例對(duì)象
User user=(User)c1.newInstance();
}
二、class類(lèi)的動(dòng)態(tài)加載
Class.forName(類(lèi)的全稱(chēng));該方法不僅表示了類(lèi)的類(lèi)型,還代表了動(dòng)態(tài)加載類(lèi)。編譯時(shí)刻加載類(lèi)是靜態(tài)加載、運(yùn)行時(shí)刻加載類(lèi)是動(dòng)態(tài)加載類(lèi)。
三、獲取方法信息
基本的數(shù)據(jù)類(lèi)型,void關(guān)鍵字都Class 類(lèi)的實(shí)例;可以通過(guò)get
ame();getSimpleName()獲取類(lèi)的名稱(chēng)。
Class c1=String.class; Class c2=int.class; Class c3=void.class; System.out.println(c1.getName()); System.out.println(c2.getSimpleName());
獲取類(lèi)的所有方法,并打印出來(lái):
public static void printClassInfo(Object object){
Class c=object.getClass();
System.out.println("類(lèi)的名稱(chēng):"+c.getName());
/**
* 一個(gè)成員方法就是一個(gè)method對(duì)象
* getMethod()所有的 public方法,包括父類(lèi)繼承的 public
* getDeclaredMethods()獲取該類(lèi)所有的方法,包括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)行:
類(lèi)的名稱(chēng):java.lang.String booleanequals(java.lang.Object,) java.lang.StringtoString() inthashCode() …
四、獲取成員變量的信息
也可以獲取類(lèi)的成員變量信息
public static void printFiledInfo(Object o){
Class c=o.getClass();
/**
* getFileds()獲取public
* getDeclaredFields()獲取所有
*/
Field[] fileds=c.getDeclaredFields();
for(Field f:fileds){
//獲取成員變量的類(lèi)型
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è)方法:需要獲取方法的名稱(chēng)和方法的參數(shù)才能決定一個(gè)方法。
方法的反射操作:
method.invoke(對(duì)象,參數(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è)對(duì)象所屬的類(lèi);在運(yùn)行時(shí)構(gòu)造任意一個(gè)類(lèi)的對(duì)象;在運(yùn)行時(shí)判斷任意一個(gè)類(lèi)所具有的成員變量和方法;在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法;生成動(dòng)態(tài)代理。
以上就是本文關(guān)于Java反射機(jī)制的全部?jī)?nèi)容,希望對(duì)大家有所幫助。
更多相關(guān)內(nèi)容可以參考:Java的RTTI和反射機(jī)制代碼分析、Java反射機(jī)制深入理解、Java 反射機(jī)制實(shí)例詳解。
相關(guān)文章
MyBatis?多表聯(lián)合查詢(xún)及優(yōu)化方法
大家都知道Hibernate 是全自動(dòng)的數(shù)據(jù)庫(kù)持久層框架,它可以通過(guò)實(shí)體來(lái)映射數(shù)據(jù)庫(kù),通過(guò)設(shè)置一對(duì)多、多對(duì)一、一對(duì)一、多對(duì)多的關(guān)聯(lián)來(lái)實(shí)現(xiàn)聯(lián)合查詢(xún),接下來(lái)通過(guò)本文給大家介紹MyBatis?多表聯(lián)合查詢(xú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ù)處理效率和用戶(hù)體驗(yàn),文中通過(guò)代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2024-10-10
Java利用TCP實(shí)現(xiàn)服務(wù)端向客戶(hù)端消息群發(fā)的示例代碼
這篇文章主要為大家詳細(xì)介紹了Java如何利用TCP協(xié)議實(shí)現(xiàn)服務(wù)端向客戶(hù)端消息群發(fā)功能,文中的示例代碼講解詳細(xì),需要的可以參考下,希望對(duì)你有所幫助2022-08-08
JsonProperty及JSONField注解的使用說(shuō)明
文章介紹了兩個(gè)常用的Java庫(kù)注解:Jackson的@JsonProperty和Fastjson的@JSONField,它們用于控制Java對(duì)象與JSON數(shù)據(jù)之間的序列化和反序列化,文章詳細(xì)說(shuō)明了這兩個(gè)注解的常見(jiàn)屬性及其使用場(chǎng)景,包括指定屬性名、控制字段可見(jiàn)性、設(shè)置默認(rèn)值和標(biāo)記字段的必需性2024-12-12
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è)算法封裝起來(lái),使得他們可以相互替換,而且算法的變化不會(huì)影響使用算法的客戶(hù)端。本文將通過(guò)案例講解如何利用Java的策略模式實(shí)現(xiàn)條件判斷,告別if----else條件硬編碼,需要的可以參考一下2022-02-02
mybatis定義sql語(yǔ)句標(biāo)簽之delete標(biāo)簽解析
這篇文章主要介紹了mybatis定義sql語(yǔ)句標(biāo)簽之delete標(biāo)簽解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
啟動(dòng)Solr提示Java版本低問(wèn)題解決方案
這篇文章主要介紹了啟動(dòng)Solr提示Java版本低問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10

