一、什么是反射
所谓的反射简单来说就是在程序运行中,动态的获取一个类的信息,并进行操作。
二、怎样动态获取到类信息
有三种方式
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){
}
三种方式各有利弊,第一种方式有点画蛇添足的意思,都new出来了,还反射干嘛,暂时想不到有什么用;第二种方式需要引入包;第三种方式使用比较普遍
三、操作
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("-----获取全部构造方法------------------");
Constructor[] constructors = c3.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
System.out.println("-------获取类属性--------------------------------");
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");
//获取一个公共构造方法并且示例化
Object obj = c3.getConstructor().newInstance();
//为属性设定值
field.set(obj, 1111);
FanSheClass fanshe = (FanSheClass) obj;
int two = fanshe.getTwo();
System.out.println(two);
System.out.println("-------获取私有字段并使用--------------------------------");
//获取指定私有字段
Field fieldPrivate = c3.getDeclaredField("one");
//获取构造函数,实例化对象
Object objp = c3.getConstructor().newInstance();
//暴力反射 获取私有变量的时候这个必须
fieldPrivate.setAccessible(true);
//给属性设置值
fieldPrivate.set(objp, 222);
//测试
FanSheClass fanshe2 = (FanSheClass) objp;
int one = fanshe2.getOne();
System.out.println(one);
System.out.println("-------获取特定方法带参数并使用------后边带的参数与方法参数一致--------------------------");
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("-------获取特定方法不带参数并使用--------------------------------");
Method method3 = c3.getDeclaredMethod("test2");
System.out.println(method3);
System.out.println("--------获取特定方法带多个参数并使用--------------------------------------");
Method method4 = c3.getDeclaredMethod("test4",String.class,String.class,int.class);
//获取构造方法实例化一个对象
Object obj3 = c3.getConstructor().newInstance();
//给方法传值
Object invoke = method4.invoke(obj3,"33","44",55);
//测试
System.out.println(invoke);
System.out.println("-----------反射调用main方法------注意String的包--------------");
//获取class对象
Class c4 = Class.forName("com.w.test.main.Enter");
//获取main方法
Method method = c4.getMethod("main",java.lang.String[].class);
//调用
Object obj4 = method.invoke(null,(Object)new String[] {"a"});
System.out.println(obj4);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
实体类:
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;
}
}
五、应用场景
不全,只是我在开发中用到的场景
1、一个接口有多个实现类,根据传入的值不同选择不同的实现类,可以使用反射获取出实现类
参考:
https://baijiahao.baidu.com/s?id=1619748187138646880&wfr=spider&for=pc