Java如何通過(guò)反射獲取Constructor、Field、Method對(duì)象
前言
在實(shí)際開(kāi)發(fā)中,通過(guò)反射可以得到一個(gè)類(lèi)的完整結(jié)構(gòu),包括類(lèi)的構(gòu)造方法、類(lèi)的屬性、類(lèi)的方法,這就需要使用到j(luò)ava.lang.reflect包中的以下幾個(gè)類(lèi):
1、Constructor:表示類(lèi)中的構(gòu)造方法
2、Field:表示類(lèi)中的屬性
3、Method:表示類(lèi)中的方法
使用反射技術(shù)獲取構(gòu)造器對(duì)象并使用
實(shí)驗(yàn)類(lèi):
public class 反射機(jī)制_2實(shí)驗(yàn)類(lèi) {
private String name;
private int age;
private 反射機(jī)制_2實(shí)驗(yàn)類(lèi)() {
System.out.println("無(wú)參構(gòu)造器執(zhí)行!");
}
public 反射機(jī)制_2實(shí)驗(yàn)類(lèi)(String name, int age) {
System.out.println("有參構(gòu)造器執(zhí)行!");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "反射機(jī)制_2實(shí)驗(yàn)類(lèi){" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
獲取構(gòu)造器對(duì)象:
import org.junit.Test;
import java.lang.reflect.Constructor;
public class 反射機(jī)制_2構(gòu)造器獲取對(duì)象 {
//1、getConstructors
//獲取全部的構(gòu)造器,只能獲取public修飾的構(gòu)造器
@Test
public void getConstructors(){
//獲取類(lèi)對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi).class;
//提取類(lèi)中的全部的構(gòu)造器對(duì)象(這里只能拿public修飾的構(gòu)造器)
Constructor[] constructors=c.getConstructors();
//遍歷構(gòu)造器
for (Constructor constructor : constructors) {
System.out.println(constructor.getName()+"\t構(gòu)造器參數(shù)個(gè)數(shù)為:"+constructor.getParameterCount()+"個(gè)");
}
//運(yùn)行結(jié)果:IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi) 構(gòu)造器參數(shù)個(gè)數(shù)為:2個(gè)
}
//2、getDeclaredConstructors
//獲取全部的構(gòu)造器:只要你敢寫(xiě),這里就能拿到,無(wú)所謂權(quán)限是否可及
@Test
public void getDeclaredConstructors(){
//獲取類(lèi)對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi).class;
//提取類(lèi)中的全部的構(gòu)造器對(duì)象
Constructor[] constructors=c.getDeclaredConstructors();
//遍歷構(gòu)造器
for (Constructor constructor : constructors) {
System.out.println(constructor.getName()+"\t構(gòu)造器參數(shù)個(gè)數(shù)為:"+constructor.getParameterCount()+"個(gè)");
}
//運(yùn)行結(jié)果:
// IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi) 構(gòu)造器參數(shù)個(gè)數(shù)為:0個(gè)
// IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi) 構(gòu)造器參數(shù)個(gè)數(shù)為:2個(gè)
}
//3、getConstructor
//獲取某個(gè)構(gòu)造器:只能拿Public修飾的某個(gè)構(gòu)造器
@Test
public void getConstructor() throws Exception {
//獲取類(lèi)對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi).class;
//定位單個(gè)構(gòu)造器對(duì)象(按照參數(shù),這里定位的是有參的構(gòu)造器)
Constructor cons=c.getConstructor(String.class,int.class);
// Constructor cons=c.getConstructor();//如果獲取無(wú)參構(gòu)造器,但因?yàn)槲以O(shè)置的是private私有的,權(quán)限不足無(wú)法獲取,便會(huì)報(bào)錯(cuò)
System.out.println(cons.getName()+"\t構(gòu)造器參數(shù)個(gè)數(shù)為:"+cons.getParameterCount()+"個(gè)");
//運(yùn)行結(jié)果:IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi) 構(gòu)造器參數(shù)個(gè)數(shù)為:2個(gè)
}
//4、getDeclaredConstructor
//獲取某個(gè)構(gòu)造器:只要你敢寫(xiě),這里就能拿到,無(wú)所謂權(quán)限是否可及
//一般是用這個(gè),什么都可以獲取,并且是根據(jù)自己需要什么而獲取
@Test
public void getDeclaredConstructor() throws Exception {
//獲取類(lèi)對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi).class;
//定位單個(gè)構(gòu)造器對(duì)象(按照參數(shù),這里定位的是有參的構(gòu)造器)
Constructor cons=c.getDeclaredConstructor(String.class,int.class);
System.out.println(cons.getName()+"\t構(gòu)造器參數(shù)個(gè)數(shù)為:"+cons.getParameterCount()+"個(gè)");
//運(yùn)行結(jié)果:IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi) 構(gòu)造器參數(shù)個(gè)數(shù)為:2個(gè)
//獲取類(lèi)對(duì)象
Class c2=反射機(jī)制_2實(shí)驗(yàn)類(lèi).class;
//定位單個(gè)構(gòu)造器對(duì)象(按照參數(shù)定位無(wú)參構(gòu)造器)
Constructor cons2=c2.getDeclaredConstructor();
System.out.println(cons2.getName()+"\t構(gòu)造器參數(shù)個(gè)數(shù)為:"+cons2.getParameterCount()+"個(gè)");
//運(yùn)行結(jié)果:IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi) 構(gòu)造器參數(shù)個(gè)數(shù)為:0個(gè)
}
}
Class在開(kāi)發(fā)中最常見(jiàn)的用法就是將Class類(lèi)對(duì)象實(shí)例化為自定義類(lèi)的對(duì)象,即可通過(guò)一個(gè)給定的字符串(類(lèi)的全限定類(lèi)名)實(shí)例化一個(gè)本類(lèi)的對(duì)象。將Class對(duì)象實(shí)例化為本類(lèi)對(duì)象時(shí),可以通過(guò)無(wú)參構(gòu)造完成,也可以通過(guò)有參構(gòu)造完成。
創(chuàng)建對(duì)象:
import org.junit.Test;
import java.lang.reflect.Constructor;
//反射可以破壞封裝性,私有的也可以執(zhí)行了
public class 反射機(jī)制_2創(chuàng)建對(duì)象 {
@Test
public void getDeclaredConstructor() throws Exception {
//獲取類(lèi)對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi).class;
//定位單個(gè)構(gòu)造器對(duì)象(按照參數(shù),這里定位的是有參的構(gòu)造器)
Constructor cons=c.getDeclaredConstructor(String.class,int.class);
System.out.println(cons.getName()+"\t構(gòu)造器參數(shù)個(gè)數(shù)為:"+cons.getParameterCount()+"個(gè)");
反射機(jī)制_2實(shí)驗(yàn)類(lèi) s1= (反射機(jī)制_2實(shí)驗(yàn)類(lèi)) cons.newInstance("狗蛋",18);
System.out.println(s1);
System.out.println();
//獲取類(lèi)對(duì)象
Class c2=反射機(jī)制_2實(shí)驗(yàn)類(lèi).class;
//定位單個(gè)構(gòu)造器對(duì)象(按照參數(shù)定位無(wú)參構(gòu)造器)
Constructor cons2=c2.getDeclaredConstructor();
System.out.println(cons2.getName()+"\t構(gòu)造器參數(shù)個(gè)數(shù)為:"+cons2.getParameterCount()+"個(gè)");
//如果遇到了私有的構(gòu)造器,可以暴力反射
cons2.setAccessible(true);//權(quán)限打開(kāi)(只是這一次有效,并不是一直打開(kāi))
反射機(jī)制_2實(shí)驗(yàn)類(lèi) s2= (反射機(jī)制_2實(shí)驗(yàn)類(lèi)) cons2.newInstance();
System.out.println(s2);
//運(yùn)行結(jié)果:
//IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi) 構(gòu)造器參數(shù)個(gè)數(shù)為:2個(gè)
//有參構(gòu)造器執(zhí)行!
//反射機(jī)制_2實(shí)驗(yàn)類(lèi){name='狗蛋', age=18}
//
//IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi) 構(gòu)造器參數(shù)個(gè)數(shù)為:0個(gè)
//無(wú)參構(gòu)造器執(zhí)行!
//反射機(jī)制_2實(shí)驗(yàn)類(lèi){name='null', age=0}
}
}
使用反射技術(shù)獲取成員變量對(duì)象并使用
實(shí)驗(yàn)類(lèi):
public class 反射機(jī)制_2實(shí)驗(yàn)類(lèi)2 {
private String name;
private int age;
public static String schoolName;
public static final String Name="遇安";
public 反射機(jī)制_2實(shí)驗(yàn)類(lèi)2() {
System.out.println("無(wú)參構(gòu)造器執(zhí)行!");
}
public 反射機(jī)制_2實(shí)驗(yàn)類(lèi)2(String name, int age) {
System.out.println("有參構(gòu)造器執(zhí)行!");
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public static String getSchoolName() {
return schoolName;
}
public static void setSchoolName(String schoolName) {
反射機(jī)制_2實(shí)驗(yàn)類(lèi)2.schoolName = schoolName;
}
@Override
public String toString() {
return "反射機(jī)制_2實(shí)驗(yàn)類(lèi)2{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
獲取成員變量:
在反射操作中可以獲取一個(gè)類(lèi)中的全部屬性,但是類(lèi)中的屬性包括兩部分,即從父類(lèi)繼承的屬性和本類(lèi)定義的屬性。因此,在獲取類(lèi)的屬性時(shí)也有以下兩種不同的方式:
1、獲取實(shí)現(xiàn)的接口或父類(lèi)中的公共屬性:public Field [] getFields throws SecurityException
2、獲取本類(lèi)中的全部屬性:public Field [] getDeclaredFields throws Exception
上述兩種方法返回的都是Field數(shù)組,每一個(gè)Field對(duì)象表示類(lèi)中的一個(gè)屬性。如果要獲取屬性中的詳細(xì)信息,就需要調(diào)用Field類(lèi)的方法。
import org.junit.Test;
import java.lang.reflect.Field;
public class 反射機(jī)制_2獲取成員變量 {
//1、獲取全部的成員變量
// Field[] getDeclaredFields
//獲得所有的成員變量對(duì)應(yīng)的Field對(duì)象,只要申明了就可以得到
@Test
public void getDeclaredFields(){
//定位Class對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi)2.class;
//定位全部成員變量
Field [] fields=c.getDeclaredFields();
//遍歷獲取,常量也會(huì)被當(dāng)做成員變量
for (Field field : fields) {
System.out.println(field.getName()+"的類(lèi)型是:"+field.getType());
}
}
//2、獲取某個(gè)成員變量對(duì)象
//Field getDeclaredField(String name)
@Test
public void getDeclaredField() throws Exception {
//定位Class對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi)2.class;
//根據(jù)名稱(chēng)定位某個(gè)成員變量
Field f=c.getDeclaredField("age");
System.out.println(f);
System.out.println(f.getName()+"的類(lèi)型是:"+f.getType());
}
}
運(yùn)行結(jié)果:
Test1、
name的類(lèi)型是:class java.lang.String
age的類(lèi)型是:int
schoolName的類(lèi)型是:class java.lang.String
COUNTTRY的類(lèi)型是:class java.lang.StringTest2、
private int IT2.反射機(jī)制_2實(shí)驗(yàn)類(lèi)2.age
age的類(lèi)型是:int
獲取了成員變量有什么用呢?
import org.junit.Test;
import java.lang.reflect.Field;
public class 反射機(jī)制_2獲取成員變量 {
//獲取了成員變量有什么用呢?
@Test
public void demo() throws Exception {
//反射第一步獲取Class對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi)2.class;
//提取某個(gè)成員變量
Field f=c.getDeclaredField("age");
f.setAccessible(true);//因?yàn)槲业腶ge成員變量是用private修飾的,所以需要暴力打開(kāi)權(quán)限
//作用一:賦值
反射機(jī)制_2實(shí)驗(yàn)類(lèi)2 s=new 反射機(jī)制_2實(shí)驗(yàn)類(lèi)2();
f.set(s,18);//s.setAge(18);
System.out.println(s);
//運(yùn)行結(jié)果:
// 無(wú)參構(gòu)造器執(zhí)行!
//反射機(jī)制_2實(shí)驗(yàn)類(lèi)2{name='null', age=18}這里可以看出,成員變量被賦值成功
//作用二:取值
int age = (int) f.get(s);
System.out.println(age);//18
}
}
使用反射技術(shù)獲取方法對(duì)象并使用
實(shí)驗(yàn)類(lèi):
public class 反射機(jī)制_2實(shí)驗(yàn)類(lèi)3 {
private String name;
public 反射機(jī)制_2實(shí)驗(yàn)類(lèi)3() {
}
public 反射機(jī)制_2實(shí)驗(yàn)類(lèi)3(String name) {
this.name = name;
}
public void run(){
System.out.println("跑起來(lái)了。。");
}
private void eat(){
System.out.println("累了,該吃飯了。。");
}
private String eat(String name){
System.out.println("那就淺吃一下"+name+"吧");
return "針不戳";
}
public static void ind(){
System.out.println("歡迎來(lái)到遇安的博客!");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
獲取成員方法:
import org.junit.Test;
import java.lang.reflect.Method;
public class 反射機(jī)制_2獲取成員方法 {
//獲得類(lèi)中的所有成員方法對(duì)象
@Test
public void getDeclaredMethods(){
//獲取類(lèi)對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi)3.class;
//提取全部方法,包括私有的
Method [] methods=c.getDeclaredMethods();
//遍歷全部方法
for (Method method : methods) {
System.out.println(method.getName()+"返回值類(lèi)型:"+method.getReturnType()+"參數(shù)個(gè)數(shù):"+method.getParameterCount());
}
}
//提取某個(gè)方法對(duì)象
@Test
public void getDeclaredMethod() throws Exception {
//獲取類(lèi)對(duì)象
Class c=反射機(jī)制_2實(shí)驗(yàn)類(lèi)3.class;
//提取單個(gè)方法對(duì)象
Method m1=c.getDeclaredMethod("eat");
Method m2=c.getDeclaredMethod("eat",String.class);
//暴力打開(kāi)權(quán)限
m1.setAccessible(true);
m2.setAccessible(true);
//觸發(fā)方法的執(zhí)行
反射機(jī)制_2實(shí)驗(yàn)類(lèi)3 s=new 反射機(jī)制_2實(shí)驗(yàn)類(lèi)3();
//注意:如果方法是沒(méi)有結(jié)果返回的,那么返回的是Null
Object result =m1.invoke(s);
System.out.println(result);
Object result2=m2.invoke(s,"海鮮大餐");
System.out.println(result2);
}
}
運(yùn)行結(jié)果:
累了,該吃飯了。。
null
那就淺吃一下海鮮大餐吧
針不戳
總結(jié)
到此這篇關(guān)于Java如何通過(guò)反射獲取Constructor、Field、Method對(duì)象的文章就介紹到這了,更多相關(guān)Java反射獲取對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Maven多模塊工程Module開(kāi)發(fā)(圖文教程)
這篇文章主要介紹了Maven多模塊工程Module開(kāi)發(fā)(圖文教程),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12
Java中的HashSet詳解和使用示例_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
HashSet 是一個(gè)沒(méi)有重復(fù)元素的集合。接下來(lái)通過(guò)實(shí)例代碼給大家介紹java中的hashset相關(guān)知識(shí),感興趣的朋友一起看看吧2017-05-05
解決Springboot中Feignclient調(diào)用時(shí)版本問(wèn)題
這篇文章主要介紹了解決Springboot中Feign?client調(diào)用時(shí)版本問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
java 學(xué)習(xí)筆記(入門(mén)篇)_程序流程控制結(jié)構(gòu)和方法
程序流程控制結(jié)構(gòu)分為:順序、選擇、循環(huán)以及異常處理結(jié)構(gòu),語(yǔ)句是程序的基本組成單位,一般來(lái)說(shuō)語(yǔ)句的執(zhí)行流程是按順序來(lái)進(jìn)行的,但是當(dāng)遇到一些特殊的條件,比如循環(huán),這時(shí)候語(yǔ)句就會(huì)按照流程控制結(jié)構(gòu)來(lái)進(jìn)行了2013-01-01
java實(shí)現(xiàn)釘釘機(jī)器人消息推送的示例代碼
這篇文章主要介紹了java實(shí)現(xiàn)釘釘機(jī)器人消息推送的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01
Springboot啟動(dòng)不檢查JPA的數(shù)據(jù)源配置方式
這篇文章主要介紹了Springboot啟動(dòng)不檢查JPA的數(shù)據(jù)源配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
SpringBoot如何通過(guò)yml方式整合Mybatis
這篇文章主要介紹了SpringBoot如何通過(guò)yml方式整合Mybatis,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04

