反射 + 暴力反射

反射

概述:
反射不需要程序员自己实现,都是底层框架或者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() 获取所有资源 --只获取自己的方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值