一啰脚、什么是反射
所謂的反射簡(jiǎn)單來(lái)說(shuō)就是在程序運(yùn)行中询张,動(dòng)態(tài)的獲取一個(gè)類(lèi)的信息,并進(jìn)行操作戒幔。
二吠谢、怎樣動(dòng)態(tài)獲取到類(lèi)信息
?有三種方式
1、
System.out.println("-----第一種反射方式------------------");
FanSheClass fs = new FanSheClass();
Class c1 = fs.getClass();
System.out.println(c1.getName());
2诗茎、
System.out.println("-----第二種反射方式------------------");
Class c2 = FanSheClass.class;
System.out.println(c2.getName());
3工坊、
System.out.println("-----第三種反射方式------------------");
Class c3 = null;
try {
c3 = Class.forName("com.w.test.fanshe.FanSheClass");
System.out.println(c3.getName());
}
catch(e){
}
三種方式各有利弊,第一種方式有點(diǎn)畫(huà)蛇添足的意思敢订,都new出來(lái)了王污,還反射干嘛,暫時(shí)想不到有什么用楚午;第二種方式需要引入包昭齐;第三種方式使用比較普遍
三、操作
package com.w.test.fanshe;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Enter {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("-----第一種反射方式------------------");
FanSheClass fs = new FanSheClass();
Class c1 = fs.getClass();
System.out.println(c1.getName());
System.out.println("-----第二種反射方式------------------");
Class c2 = FanSheClass.class;
System.out.println(c2.getName());
System.out.println("-----第三種反射方式------------------");
Class c3 = null;
try {
c3 = Class.forName("com.w.test.fanshe.FanSheClass");
System.out.println(c3.getName());
System.out.println("-----獲取全部構(gòu)造方法------------------");
Constructor[]? constructors = c3.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("-------獲取類(lèi)屬性--------------------------------");
System.out.println("-------獲取所有的公共字段--------------------------------");
Field[] fields = c3.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("-------獲取所有的字段,公共的私有的--------------------------------");
Field[] fields2 = c3.getDeclaredFields();
for (Field field : fields2) {
System.out.println(field);
}
System.out.println("-------獲取公有字段并使用--------------------------------");
//獲取指定公有字段
Field field = c3.getField("two");
//獲取一個(gè)公共構(gòu)造方法并且示例化
Object obj = c3.getConstructor().newInstance();
//為屬性設(shè)定值
field.set(obj, 1111);
FanSheClass fanshe = (FanSheClass) obj;
int two = fanshe.getTwo();
System.out.println(two);
System.out.println("-------獲取私有字段并使用--------------------------------");
//獲取指定私有字段
Field fieldPrivate = c3.getDeclaredField("one");
//獲取構(gòu)造函數(shù)矾柜,實(shí)例化對(duì)象
Object objp = c3.getConstructor().newInstance();
//暴力反射? 獲取私有變量的時(shí)候這個(gè)必須
fieldPrivate.setAccessible(true);
//給屬性設(shè)置值
fieldPrivate.set(objp, 222);
//測(cè)試
FanSheClass fanshe2 = (FanSheClass) objp;
int one = fanshe2.getOne();
System.out.println(one);
System.out.println("-------獲取特定方法帶參數(shù)并使用------后邊帶的參數(shù)與方法參數(shù)一致--------------------------");
Method method1 = c3.getMethod("test1", String.class);
Method method2 = c3.getMethod("test5", int.class);
System.out.println(method1);
System.out.println(method2);
System.out.println("-------獲取特定方法不帶參數(shù)并使用--------------------------------");
Method method3 = c3.getDeclaredMethod("test2");
System.out.println(method3);
System.out.println("--------獲取特定方法帶多個(gè)參數(shù)并使用--------------------------------------");
Method method4 = c3.getDeclaredMethod("test4",String.class,String.class,int.class);
//獲取構(gòu)造方法實(shí)例化一個(gè)對(duì)象
Object obj3 = c3.getConstructor().newInstance();
//給方法傳值
Object invoke = method4.invoke(obj3,"33","44",55);
//測(cè)試
System.out.println(invoke);
System.out.println("-----------反射調(diào)用main方法------注意String的包--------------");
//獲取class對(duì)象
Class c4 = Class.forName("com.w.test.main.Enter");
//獲取main方法
Method method = c4.getMethod("main",java.lang.String[].class);
//調(diào)用
Object obj4 = method.invoke(null,(Object)new String[] {"a"});
System.out.println(obj4);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
實(shí)體類(lèi):
package com.w.test.fanshe;
public class FanSheClass {
private int one;
public int two;
public static int four;
String three;
public int getTwo() {
return two;
}
public void setTwo(int two) {
this.two = two;
}
public void test1(String aa) {
System.out.println(aa);
}
public void test5(int aa) {
System.out.println(aa);
}
public String test4(String aa, String nn, int cc) {
System.out.println(aa + nn + cc);
return aa + nn + cc;
}
public String test2() {
return "111";
}
String test3() {
return "222";
}
public int getOne() {
return one;
}
public void setOne(int one) {
this.one = one;
}
}
五阱驾、應(yīng)用場(chǎng)景
不全,只是我在開(kāi)發(fā)中用到的場(chǎng)景
1怪蔑、一個(gè)接口有多個(gè)實(shí)現(xiàn)類(lèi)啊易,根據(jù)傳入的值不同選擇不同的實(shí)現(xiàn)類(lèi),可以使用反射獲取出實(shí)現(xiàn)類(lèi)
參考:
https://baijiahao.baidu.com/s?id=1619748187138646880&wfr=spider&for=pc