反射 + 暴力反射
Posted liang-shi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反射 + 暴力反射相关的知识,希望对你有一定的参考价值。
反射
概述: 反射不需要程序员自己实现,都是底层框架或者JVM去使用的一个技术. 专门用来解析 .class文件里 的所有数据 (公开的,私有的) 2,原理 把解析 到的 .class里的数据 封装成了Class工具类 3,怎么获取Class对象 Class对象是 封装了.class文件里的数据 ,,可以通过Class对象提供的种方法解析数据 static Class<?> forName(String className) 类名.class 对象.getClass()
反射
测试获取Class对象
public class C1 {
public static void main(String[] args) throws ClassNotFoundException {
method();//获取Class对象
}
//获取Class对象--用来解析.class文件里的所有数据
public static void method() throws ClassNotFoundException {
//参数是类的全路径 -- 包名.类名
Class c = Class.forName("java.lang.String");
Class c2 = String.class;
Class c3 = new String().getClass();
System.out.println(c);
System.out.println(c2);
System.out.println(c3);
}
}
反射Student类里的所有信息
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class C1_Student {
public static void main(String[] args) throws Exception {
//1,获取Student类的Class对象
Class s = Student.class;
//method(s);//解析 构造方法
//method2(s);//解析 成员变量
//method3(s);//解析 成员方法
//method4(s);//用反射 创建对象
//method5(s);//用反射 设置变量的值
method6(s);//用反射 执行方法
}
//用反射 执行方法
public static void method6(Class s) throws Exception {
//获取指定的方法 public void test(int a)
Method m = s.getMethod("test", int.class);
Object o = s.newInstance();
//invoke(m,n)--m是对象--n是要给方法传入的参
m.invoke(o,50);//执行方法
}
//用反射 设置变量的值
public static void method5(Class s) throws Exception {
//TODO public String name ;
Field f = s.getField("name");
Object o = s.newInstance();
//set(m,n)--m是对象--n是想要设置啥值
f.set(o,"jack");//设置值
System.out.println( f.get(o) );//获取值
}
//用反射 创建对象
public static void method4(Class s) throws Exception{
//用反射new --自动调用无参构造
Object o = s.newInstance();
Student s2 = (Student) o ;//向下转型,目的是使用子类的特有功能
s2.show();//使用了Student类里功能
}
//解析Student.class文件中的 成员方法
//getMethods() getMethod() -- 获取自己和父类的所有 公开的方法
public static void method3(Class s) throws NoSuchMethodException {
//获取 所有方法
Method[] ms = s.getMethods();
//遍历数组,获取每个方法m
for (Method m : ms) {
System.out.println( m.getName() );//获取方法名
Class[] c = m.getParameterTypes();//获取参数类型
System.out.println( Arrays.toString(c) );
}
//TODO 获取 特定的方法 public void test(int a)
Method m = s.getMethod("test", int.class);
System.out.println( m.getName() );
}
//解析Student.class文件中的 成员变量
//getFields() getField() --获取公开的
public static void method2(Class s) throws Exception {
//获取所有 成员变量们~~~~
Field[] fs = s.getFields();
//遍历,得到每个成员变量f
for (Field f : fs){
//获取变量名
System.out.println(f.getName());
//获取变量类型
System.out.println(f.getType().getName());
}
//根据属性名获取属性
Field f = s.getField("name");
//获取属性类型
System.out.println(f.getType().getName());
}
//解析Student.class文件中的构造方法
//getConstructors() getConstructor()--获取公开的
public static void method(Class s) throws NoSuchMethodException {
//获取 所有的构造方法 存入Constructor[]
Constructor[] cs = s.getConstructors();
//遍历数组,得到每个构造方法c
for (Constructor c: cs
) {
//获取构造方法的 名称
System.out.println(c.getName());
//TODO 解析构造方法的 参数的类型
Class[] cc =c.getParameterTypes();
System.out.println(cc);
}
//TODO 获取指定的构造方法 --public Student(int age)
//getConstructor()的参数是 构造方法的参数类型 的Class对象
Constructor con = s.getConstructor(int.class);
System.out.println(con.getName()+"--");
}
}
暴力反射 --1,概述 专门用来 反射 类中的 公开数据 和 私有数据 --2,新的API --普通反射 -- 只能获取public的 getMethod() getMethods() getField() getFields() getConstructor() getConstructors()
--暴力反射 --除了public的甚至连private都可以获取 getDeclaredMethod() getDeclaredMethods() getDeclaredField()
getDeclaredFields() getDeclaredConstructor() getDeclaredConstructors()
--创建Person类
public class Person {
private String name;
int age;
public char sex;
private void show(){
System.out.println("show..");
}
void test(int a){
System.out.println("test.."+a);
}
}
--创建测试类
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test3_Person {
public static void main(String[] args) throws Exception {
// method();//暴力反射 成员变量
method2();//暴力反射 成员方法
}
//TODO 暴力反射成员方法
public static void method2() throws Exception {
Class c = Person.class;
//暴力反射--获取所有方法
Method[] ms = c.getDeclaredMethods();
//遍历数组,获取每个方法m
for (Method m : ms) {
//获取方法名
System.out.println(m.getName());
}
//TODO 获取指定的方法
Method m = c.getDeclaredMethod("show");
Object oo = c.newInstance();
m.setAccessible(true);//开启 私有资源的 访问权限
m.invoke(oo);
}
//TODO 暴力反射成员变量
public static void method() throws Exception {
Class c = Person.class;
//暴力反射--获取所有属性,包括 public的private的default的
Field[] fs = c.getDeclaredFields();
//遍历数组,得到每个属性f
for (Field f : fs) {
//获取属性名
System.out.println( f.getName() );
}
//只获取一个私有的属性
Field f = c.getDeclaredField("name");
Object o = c.newInstance();
//对私有的属性操作抛出异常:IllegalAccessException
f.setAccessible(true);//开启私有的访问权限
f.set(o,"jack");//设置值
System.out.println( f.get(o) );//获取值
}
}
反射和暴力反射的区别
总结: 1, 普通反射 和 暴力反射 的区别 ? 暴力反射是可以获取public的甚至private 普通反射只能获取public的
2, 怎么使用暴力反射? 用对API ( getDeclaredXxx() ) 设置访问权限( setAccessible(true) )
3, getDeclaredXxx() 和 getXxx() 的区别?? getXxx() 获取public资源 -- 获取自己的方法和父类的方法 getDeclaredXxx() 获取所有资源 --只获取自己的方法
以上是关于反射 + 暴力反射的主要内容,如果未能解决你的问题,请参考以下文章