反射的基本使用
参考资料:https://www.liaoxuefeng.com/wiki/1252599548343744/1255945147512512 。
反射的基本概念和使用场景本文不提,写一下简单的练习使用和总结。
一 基本使用
- 1 类对象获取的三种方式
public class Person {}
//获取对象
1 Person p = new Person();
2 Class c = Person.class;
3 Class c = p.getClass();
4 Class c = Class.forName("package.Person");
- 2 Class获取类对象信息后可执行操作
1 获取类名、类修饰符、父类、接口 等
2 通过反射的方式获取字段信息,并可以进行set get
3 通过反射的方式获取方法类,根据方法名称获取方法实例并执行
4 通过反射的方式获取构造器类,并将其实例化
5 动态代理实现接口的动态实现,无须具体的实现类
二 代码示例
1 测试主类
package testInvoke;
import org.junit.Test;
import java.lang.reflect.*;
/**
* @author r
* @description 测试反射
* @date 2020/11/26
*/
public class WebRequest {
/**
* 反射获取字段信息
* @throws Exception
*/
@Test
public void field1() throws Exception {
Class ucl = UserServer.class;
System.out.println("----------0-----------");
System.out.println(ucl.getName());
System.out.println(ucl.getSuperclass().getName());
System.out.println(ucl.getInterfaces().length);
for(Class i : ucl.getInterfaces()){
System.out.println(i.getName());//只返回当前类直接实现的接口
}
System.out.println("----------1-----------");
System.out.println("===ucl.getFields()===");
for (Field field:ucl.getFields()) {
System.out.println(field.toString());
System.out.println(field.getName());
System.out.println(field.getType());
System.out.println(field.getModifiers());
System.out.println(Modifier.isPublic(field.getModifiers()));
System.out.println(Modifier.isAbstract(field.getModifiers()));
}
System.out.println("----------2-----------");
System.out.println(ucl.getField("ttt").toString());
System.out.println("----------3-----------");
System.out.println("===ucl.getDeclaredFields()===");
for (Field field:ucl.getDeclaredFields()) {
System.out.println(field.toString());
}
}
/**
* 反射获取public字段信息
* @throws Exception
*/
@Test
public void field2(){
UserServer u = new UserServer("测试字段!");
Class ucl = u.getClass();
Field field = null;
try {
field = ucl.getDeclaredField("xxx");
} catch (NoSuchFieldException e) {
System.out.println("UserServer类xxx字段 不存在");
}
try {
Object o = field.get((Object) u);
System.out.println(o.toString()); //测试字段!
} catch (IllegalAccessException e) {
System.out.println("字段获取失败,检查字段访问权限");
}
}
/**
* 反射 获取/设置 private字段信息
* @throws Exception
*/
@Test
public void field3(){
UserServer u = new UserServer("测试字段xxx","测试字段xxx1");
Class ucl = u.getClass();
Field field = null;
try {
field = ucl.getDeclaredField("xxx1");
} catch (NoSuchFieldException e) {
System.out.println("UserServer类xxx字段 不存在");
}
/**
*获取私有变量需设置此参数
* 调用Field.setAccessible(true)的意思是,别管这个字段是不是public,一律允许访问。
*/
field.setAccessible(true);
try {
Object o = field.get((Object) u);
System.out.println(o.toString()); //测试字段xxx1
} catch (IllegalAccessException e) {
System.out.println("字段获取失败,检查字段访问权限");
}
try {
field.set(u,"测试字段===");
System.out.println(u.toString()); //UserServer{xxx='测试字段xxx', xxx1='测试字段==='}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
/**
* 反射实现方法调用,当调用非public方法时,需:Method.setAccessible(true);同上。
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
@Test
public void method1() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
UserServer u = new UserServer("测试字段xxx","测试字段xxx1");
Class ucl = u.getClass();
//非静态方法
Method m = ucl.getDeclaredMethod("see", String.class, int.class);
m.invoke(u,"Hello, 世界",100); //Hello, 世界 ; Let me see see! ; 100
//静态方法
Method sm = ucl.getDeclaredMethod("see");
sm.invoke(null); //Let me see see!
}
/**
* 多态
*/
@Test
public void method2() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
TestUser testUser = new TestUser();
Class cl = testUser.getClass();
Method m = cl.getDeclaredMethod("hello");
m.invoke(new UserServer()); //UserServer{xxx='null', xxx1='null'}
}
/**
* 构造器创建对象
*/
@Test
public void constru1() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class cl = UserServer.class;
Constructor cons = cl.getConstructor(String.class);
UserServer u = (UserServer)cons.newInstance("xxx");
System.out.println(u.toString());
}
/**
* 动态代理,实现接口的动态实现(无需具体的实现类)
* interface Use(){}
*/
@Test
public void proxyion(){
InvocationHandler handler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(method.getName().equals("find")){
System.out.println("接口 Use 的 find 方法 的实现!");
}
return null;
}
};
Use use = (Use)Proxy.newProxyInstance(
Use.class.getClassLoader(),
new Class[]{Use.class},
handler
);
use.find();
}
}
2 UserServer.class
package testInvoke;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UserServer extends TestUser {
public String xxx;
private String xxx1;
private static final Logger logger = LoggerFactory.getLogger(UserServer.class);
public UserServer() {
}
public UserServer(String xxx) {
this.xxx = xxx;
}
public UserServer(String xxx, String xxx1) {
this.xxx = xxx;
this.xxx1 = xxx1;
}
@Override
public String toString() {
return "UserServer{" +
"xxx='" + xxx + '\'' +
", xxx1='" + xxx1 + '\'' +
'}';
}
@Override
public void hello() {
String s = "UserServer{" +
"xxx='" + xxx + '\'' +
", xxx1='" + xxx1 + '\'' +
'}';
System.out.println(s);
}
public void run (){
System.out.println("Let me run run!");
}
public static void see (){
System.out.println("Let me see see!");
}
public void see (String a1,int a2){
System.out.println(a1 + " ; Let me see see! ; "+a2);
}
}
3 TestUser.class
package testInvoke;
/**
* @author r
* @description 测试UserServer父类
* @date 2020/12/3
*/
public class TestUser {
public Integer ttt;
public void hello() {
String s = "TestUser{" +
"ttt=" + ttt +
'}';
System.out.println(s);
}
}
4 Use.class
package testInvoke;
public interface Use {
void find();
}