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

