prophet
- 关注
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
引言
致力于用最简单的话语,去方法师傅们的学习,开设 java安全的学习板块 。
本篇文章分为三个板块,反射与反序列化的学习,以及urldns链条的跟踪原理。
反射
当我们创建一个新对象时,用idea快捷键Ctrl+p就可以直接看到我们构造对象所需要的形参,这时候我们就不禁思考,为什么能够直接看到的?
其实这里的就是调用了反射,获取方法的参数并且将其反馈到我们的屏幕上。
反射首先需要获取class文件,以下为最常见的三种获取class文件的方法。
- Class.forName(全类名) //源代码阶段
- 类名.class //加载阶段
- 对象.getClass() //运行阶段
通过获取其字节码文件便可调用其中的方法。
getConstructor() 获取某种构造方法
getConstructors() 获取所有公共构造方法
getDclaredConstructors() 获取所有构造方法包括私有
getParameter() 获取某个参数变量
getParameters() 获取所有参数变量
getFiled() 获取某个成员属性
getFileds() 获取所有成员属性
getDclaredFileds() 获取所有包括私有成员属性
getMethod() 获取所有公共方法包括父类
getDclaredMethod() 获取所有方法包括私有除父类
invoke(对象 ,参数) 执行方法
这里还有反射的newInsatnce方法,这个作用就跟new的作用一样,正如他的意思新的实例,两个本质上的区别就是newInsatnce调用需要先加载这个类的字节码文件,而new不需要。
案例
此处举一个代码示例方便理解
import java.lang.reflect.Field;
public class SerializeTest {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
Class<?> aClass = Class.forName("com.zyf.User");
Field name = aClass.getDeclaredField("name");
name.setAccessible(true);
//这里的setAccessible相当于给了临时访问私有成员的权限
User u = new User("张三", 18);
Object o = name.get(u);
//获取u对象中的name成员值
System.out.println(o);
name.set(u,"李四");
//将u的name成员值重新设置为李四
System.out.println(u.getName());
Method s = aClass.getDeclaredMethod("sing", String.class);
s.setAccessible(true);
//同理,具有访问私有方法的临时权限
User user = new User();
s.invoke(user,"奇迹再现");
//触发sing方法
}
}
可以看到成功执行
畅读付费文章
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)