Java 反射,开发框架必备技能
时间:2022-05-03
本文章向大家介绍Java 反射,开发框架必备技能,主要内容包括1.9. Reflection 反射、1.9.2. 批量赋值、1.9.3. 方法操作、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
反射一般开发者接触不到,反射主要用户框架的开发。例如我举一个例子你就明白了:
http://www.netkiller.cn/news/list/2.html
通过反射技术我们将上面的统一资源定位付(URL) 映射到Class 相当于
class: news
method: list
parameter: 2
差不多就是下面样子
class News{
public String list(String catagory_id){
...
...
}
}
我们只需要在框架核心中分析 url 然后调用对应的方法,于此同时将参数传递过去。
Class<?> cls = Class.forName("cn.netkiller.reflect.News");
Object obj= cls.newInstance();
Method method = cls.getDeclaredMethod("list", int.class);
return method.invoke(obj, 2);
本文节选自《Netkiller Java 手札》
1.9. Reflection 反射
this.getClass().getName() //当前Class名字
Thread.currentThread().getStackTrace()[1].getMethodName()); //当前方法名
1.9.1. 获得所有变量
Field[] fields = objClass.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}
注意:只能去除 public变量
1.9.2. 批量赋值
1.9.3. 方法操作
JAVA反射调用方法的步骤有三步
得到要调用类的class
得到要调用的类中的方法(Method)
方法调用(invoke)
1.9.3.1. 获得所有方法
Class<?> objClass = a.getClass();
Method[] methods = objClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
1.9.3.2. set/get 方法
package cn.netkiller.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Member {
public String name;
private int 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 "ClassA [name=" + name + ", age=" + age + "]";
}
public Member() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
Class<?> cls = Class.forName("cn.netkiller.reflect.Member");
Object member = cls.newInstance();
Method setMethod = cls.getDeclaredMethod("setAge", int.class);
setMethod.invoke(member, 15);
Method getMethod = cls.getDeclaredMethod("getAge");
System.out.println(getMethod.invoke(member));
}
}
下面做一个稍微复杂点的例子,ClassB继承ClassA,取出ClassA的成员变量赋值到ClassA。
package cn.netkiller.reflect;
public class ClassA {
public String name;
private int 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 ClassA() {
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "ClassA [name=" + name + ", age=" + age + "]";
}
}
package cn.netkiller.reflect;
public class ClassB extends ClassA{
public ClassB() {
// TODO Auto-generated constructor stub
}
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "ClassB [address=" + address + "]";
}
}
package cn.netkiller.reflect;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectionTest {
public ReflectionTest() {
// TODO Auto-generated constructor stub
}
public void testSetMethod() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException {
// ClassA a = new ClassA();
ClassB b = new ClassB();
b.setAddress("Shenzhen");
Class<ClassA> classA = ClassA.class;
ClassA a = classA.newInstance();
a.setName("Neo");
a.setAge(30);
System.out.println(classA.getDeclaredMethod("getAge").invoke(a));
Method m = classA.getDeclaredMethod("setAge", int.class);
m.setAccessible(true); // 因为写成private 所以这里必须设置
m.invoke(b, 26);
System.out.println(a.toString());
System.out.println(b.toString());
System.out.println(b.getName());
System.out.println(b.getAge());
}
public static void main(String[] args) throws InvocationTargetException {
ReflectionTest rt = new ReflectionTest();
try {
rt.testSetMethod();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
set 方法
System.out.println(classA.getDeclaredMethod("getAge").invoke(a));
get 方法
Method m = classA.getDeclaredMethod("setAge", int.class);
m.setAccessible(true); //因为写成private 所以这里必须设置
m.invoke(b, 26);
1.9.3.3. static 方法调用
Class cls = Class.forName("cn.netkiller.reflect.Student");
Method setMethod = cls.getDeclaredMethod("setAge",int.class);
setMethod.invoke(cls.newInstance(), 15);
static 方法调用时,不必得实例化对象
Class cls = Class.forName("cn.netkiller.reflect.Student");
Method staticMethod = cls.getDeclaredMethod("setAge",int.class);
staticMethod.invoke(cls,20); //这里不需要newInstance
- 利用HTC One漏洞破解手机PIN密码
- Android NDk环境配置
- 谷歌再曝Windows8.1漏洞,微软怒了
- Python机器学习的生态系统
- TP-link TL-WR840N系列路由器存在CSRF漏洞,可修改任意配置(含POC测试过程)
- JavaScript严格模式
- 微软修复8个安全漏洞,包括谷歌披露的0day漏洞
- PullToRefreshScrollView 嵌套RecyclerView实现特卖列表倒计时抢购
- 全栈数据工程师养成攻略:Python 基本语法
- 从卷积神经网络的角度看世界
- 外观模式
- 透析挖洞神器mona.py插件新特性
- Python学习没有捷径,但可以加速,零基础九天你也可以会编程
- Activity状态和生命周期方法
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 疯子的算法总结(九) 图论中的矩阵应用 Part 1 POJ3613 Cow Relays
- 『数据库』你这些知识点都不会,你学个锤子SQL数据库!
- The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 XKC's basketball team
- The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 D Carneginon
- 地表最强的MySQL安装一键式安装,信不信你下完我就给你装好!附各种Mysql安装失败的解决办法(什么你安装失败了?快来看这个)
- The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 C Buy Watermelon
- The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 B so easy
- 萌新不看会后悔的C++基本类型总结(二)
- The Preliminary Contest for ICPC Asia Xuzhou 2019 徐州网络赛 A Who is better?
- 树的重心
- PostgreSQL 13:索引并行vacuum
- 『数据库』震惊,某博主为吸引眼球拿出压箱底SQL总结,如果你没看那就吃亏了!(超级详细的SQL基础,你还不会的话就别学数据库了)
- 萌新不看会后悔的C++基本类型总结(一)
- 2019 ICPC 银川网络赛 D. Take Your Seat (疯子坐飞机问题)
- 2019 ICPC 银川网络赛 H. Fight Against Monsters