Java 反射機(jī)制實(shí)例詳解
Java 反射機(jī)制實(shí)例詳解
一、JAVA是動(dòng)態(tài)語(yǔ)言嗎?
一般而言,說(shuō)到動(dòng)態(tài)言,都是指在程序運(yùn)行時(shí)允許改變程序結(jié)構(gòu)或者變量類型,從這個(gè)觀點(diǎn)看,Java和C++一樣,都不是動(dòng)態(tài)語(yǔ)言。
但JAVA它卻有著一個(gè)非常突出的動(dòng)態(tài)相關(guān)機(jī)制:反射。通過(guò)反射,Java可以于運(yùn)行時(shí)加載、探知和使用編譯期間完全求和的類、生成其對(duì)象實(shí)體,調(diào)用其方法或者對(duì)屬性設(shè)值。所以Java算是一個(gè)半動(dòng)態(tài)的語(yǔ)言吧。
反射的概念:
在Java中的反射機(jī)制是指在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;
對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法;
這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為Java語(yǔ)言的反射機(jī)制
二、動(dòng)態(tài)性質(zhì)
2.1、動(dòng)態(tài)性質(zhì)
運(yùn)行時(shí)生成對(duì)象實(shí)例;
運(yùn)行期間調(diào)用方法;
運(yùn)行時(shí)更改屬性
2.2、Java反射機(jī)制能實(shí)現(xiàn)的功能
在運(yùn)行時(shí)判斷任意一個(gè)對(duì)象所屬的類
在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對(duì)象
在運(yùn)行時(shí)判斷任意懷個(gè)類所具有的方法和屬性
在運(yùn)行時(shí)調(diào)用任意一個(gè)對(duì)象的方法
生成動(dòng)態(tài)代理
2.3、Java反射應(yīng)用場(chǎng)合
在Java程序中許多對(duì)象在運(yùn)行時(shí)都會(huì)出現(xiàn)兩種類型:編譯時(shí)類型和運(yùn)行時(shí)類型
編譯時(shí)的類型由聲明該對(duì)象時(shí)使用的類型決定,運(yùn)行時(shí)的類型由實(shí)際賦給對(duì)象的類型決定
如:
Person p =new Student();
編譯時(shí)類型為Person,而運(yùn)行時(shí)為Student
除此之外,程序在運(yùn)行時(shí)還可能接收到外部傳入的一個(gè)對(duì)象,該對(duì)象的編譯時(shí)類型為Object,但程序又需要調(diào)用該對(duì)象運(yùn)行時(shí)類型的方法。為了這些問(wèn)題程序需要在運(yùn)行時(shí)發(fā)現(xiàn)對(duì)象和類的真實(shí)信息。然而,如果編譯時(shí)根本無(wú)法預(yù)知該對(duì)象和類可能屬于哪些類,程序只依靠運(yùn)行時(shí)信息來(lái)發(fā)現(xiàn)該對(duì)象和類的真實(shí)信息,此時(shí)就必須使用反射
三、Java反射API
反射API用來(lái)生成在當(dāng)前JAVA虛擬機(jī)中的類、接口或者對(duì)象的信息。
Class類:反射的核心類,可以獲取類的屬性,方法等內(nèi)容信息。
Field類:Java.lang.reflect.表示類的屬性,可以獲取和設(shè)置類的中屬性值。
Method類:Java.lang.reflect。表示類的方法,它可以用來(lái)獲取類中方法的信息或者執(zhí)行方法
Construcor類:Java.lang.reflect。表示類的構(gòu)造方法。
四、獲取全部方法和屬性
Person類
package com.pb.Reflect.classinfo;
public class Person {
private String name;
private String gender;
private int age;
private Person() {
//
}
public Person(String name, String gender, int age) {
super();
this.name = name;
this.gender = gender;
this.age = age;
}
//getter、和setter方法
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "姓名:"+name+"年齡: "+age;
}
}
使用反射:
package com.pb.Reflect.classinfo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.JOptionPane;
/*
* 通過(guò)用戶輸入類的全路徑,來(lái)獲取該類的成員方法和屬性
* Declared獲取全部不管是私有和公有
* 1.獲取訪問(wèn)類的Class對(duì)象
* 2.調(diào)用Class對(duì)象的方法返回訪問(wèn)類的方法和屬性信息
*/
public class ReflectDemo {
/*
* 構(gòu)造方法
*/
public ReflectDemo(){
//用戶輸入類的全路徑徑
//使用String組件
String classpsth=JOptionPane.showInputDialog(null,"輸入類的全路徑");
//使用Class.forName方法根據(jù)輸入的類的全路徑 返回該類的Class對(duì)象
try {
Class cla = Class.forName(classpsth);
//利用Class對(duì)象的cla的自審,返回方法對(duì)象集合
Method [] method=cla.getDeclaredMethods(); //返回所有的方法
System.out.println("========獲取方法信息============");
for (Method meth : method) {
//遍歷method數(shù)組,并輸出方法信息
System.out.println(meth.toString());
}
System.out.println("========獲取出方法信息結(jié)束============");
//獲取屬性利用Class對(duì)象的cla的自審,返回成員屬性對(duì)象集合
Field [] field=cla.getDeclaredFields();
System.out.println("========獲取成員屬性信息============");
for (Field f : field) {
System.out.println(f.toString());
}
System.out.println("========獲取成員屬性信息結(jié)束============");
//獲取屬性利用Class對(duì)象的cla的自審,返回構(gòu)造方法集合
Constructor [] constructor=cla.getDeclaredConstructors();
System.out.println("========獲取成員構(gòu)造方法信息============");
for (Constructor constru : constructor) {
System.out.println(constru.toString());
}
System.out.println("========獲取成員構(gòu)造方法信息結(jié)束============");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("路徑輸入錯(cuò)誤!");
}
}
}
package com.pb.Reflect.classinfo;
public class TestReflection {
public static void main(String[] args) {
ReflectDemo rd=new ReflectDemo();
}
}
輸入com.pb.Reflect.classinfo.Person
結(jié)果:
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge(int) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結(jié)束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結(jié)束============ ========獲取構(gòu)造方法信息============ private com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int) ========獲取構(gòu)造方法信息結(jié)束============
五、使用反射的步驟
5.1、步驟
Java.lang.reflect
獲得想操作類的Java.lang.Class對(duì)象
調(diào)用Class的方法
使用反射API來(lái)操作這些信息
5.2、獲取Class對(duì)象方式
調(diào)用某個(gè)對(duì)象的getClass()方法
Person p = new Person(); Class cla=p.getClass();
調(diào)用某個(gè)類的class屬性來(lái)獲取該類對(duì)應(yīng)的Class對(duì)象
Class cls=Person.class;
使用Class類的forName()靜態(tài)方法
Class cla=Class.forName(“類的全路徑”);
六、第二種方式對(duì)象的getClass()方法
Person類,因?yàn)橐暶鲗?duì)象所以將構(gòu)造方法public
package com.pb.Reflect.classinfo;
public class Person {
private String name;
private String gender;
private int age;
public Person() {
//
}
public Person(String name, String gender, int age) {
super();
this.name = name;
this.gender = gender;
this.age = age;
}
//getter、和setter方法
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "姓名:"+name+"年齡: "+age;
}
}
使用反射:
package com.pb.Reflect.classinfo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.JOptionPane;
/*
* 通過(guò)用戶輸入類的全路徑,來(lái)獲取該類的成員方法和屬性
* Declared獲取全部不管是私有和公有
* 1.獲取訪問(wèn)類的Class對(duì)象
* 2.調(diào)用Class對(duì)象的方法返回訪問(wèn)類的方法和屬性信息
*/
public ReflectDemo(Person p){
Class cla=p.getClass();
//利用Class對(duì)象的cla的自審,返回方法對(duì)象集合
Method [] method=cla.getDeclaredMethods(); //返回所有的方法
System.out.println("========獲取方法信息============");
for (Method meth : method) {
//遍歷method數(shù)組,并輸出方法信息
System.out.println(meth.toString());
}
System.out.println("========獲取出方法信息結(jié)束============");
//獲取屬性利用Class對(duì)象的cla的自審,返回成員屬性對(duì)象集合
Field [] field=cla.getDeclaredFields();
System.out.println("========獲取成員屬性信息============");
for (Field f : field) {
System.out.println(f.toString());
}
System.out.println("========獲取成員屬性信息結(jié)束============");
//獲取屬性利用Class對(duì)象的cla的自審,返回構(gòu)造方法集合
Constructor [] constructor=cla.getDeclaredConstructors();
System.out.println("========獲取成員構(gòu)造方法信息============");
for (Constructor constru : constructor) {
System.out.println(constru.toString());
}
System.out.println("========獲取成員構(gòu)造方法信息結(jié)束============");
}
}
測(cè)試類
package com.pb.Reflect.classinfo;
public class TestReflection {
public static void main(String[] args) {
Person p=new Person();
ReflectDemo rd=new ReflectDemo(p);
}
}
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge(int) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結(jié)束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結(jié)束============ ========獲取成員構(gòu)造方法信息============ public com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int) ========獲取成員構(gòu)造方法信息結(jié)束============
七、第三種方法類的.class屬性
Person類同上
測(cè)試類:
package com.pb.Reflect.classinfo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestReflection {
public static void main(String[] args) {
/*第二種方法
Person p=new Person();
ReflectDemo rd=new ReflectDemo(p);
*/
/*
* 第三種方式.class屬性
*/
Class cla=Person.class;
//利用Class對(duì)象的cla的自審,返回方法對(duì)象集合
Method [] method=cla.getDeclaredMethods(); //返回所有的方法
System.out.println("========獲取方法信息============");
for (Method meth : method) {
//遍歷method數(shù)組,并輸出方法信息
System.out.println(meth.toString());
}
System.out.println("========獲取出方法信息結(jié)束============");
//獲取屬性利用Class對(duì)象的cla的自審,返回成員屬性對(duì)象集合
Field [] field=cla.getDeclaredFields();
System.out.println("========獲取成員屬性信息============");
for (Field f : field) {
System.out.println(f.toString());
}
System.out.println("========獲取成員屬性信息結(jié)束============");
//獲取屬性利用Class對(duì)象的cla的自審,返回構(gòu)造方法集合
Constructor [] constructor=cla.getDeclaredConstructors();
System.out.println("========獲取成員構(gòu)造方法信息============");
for (Constructor constru : constructor) {
System.out.println(constru.toString());
}
System.out.println("========獲取成員構(gòu)造方法信息結(jié)束============");
}
}
結(jié)果:
同上
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge(int) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結(jié)束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結(jié)束============ ========獲取成員構(gòu)造方法信息============ public com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int) ========獲取成員構(gòu)造方法信息結(jié)束============
如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
相關(guān)文章
聊聊spring boot的WebFluxTagsProvider的使用
這篇文章主要介紹了聊聊spring boot的WebFluxTagsProvider的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
Java多線程(單例模式,阻塞隊(duì)列,定時(shí)器,線程池)詳解
本文是多線程初級(jí)入門(mén),主要介紹了多線程單例模式、阻塞隊(duì)列、定時(shí)器、線程池、多線程面試考點(diǎn),感興趣的小伙伴可以跟隨小編一起了解一下2022-09-09
SpringBoot WebService服務(wù)端&客戶端使用案例教程
這篇文章主要介紹了SpringBoot WebService服務(wù)端&客戶端使用案例教程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-10-10

