java反射爆破


反射爆破创建实例

假设现在有这样一个实体类

class User{
    private int age=10;
    private String name="杨宸";

    public User(){
        //无参 public
    }
    public User(String name){//public的有参构造器
        this.name=name;
    }
    private User(int age,String name){//私有的有参构造
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

里面有public无参构造器 public有参构造器 和一个私有的有参构造器,对于创建一个实例来说,我们可以使用这三种构造器的任意一种
对于public无参构造器来说

public class ReflecCreateInstance {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //1.先获取到User类的Class对象
        Class<?> userClass = Class.forName("Reflection.User");
        //2.通过public的无参构造器创建实例
        Object o = userClass.newInstance();
        System.out.println(o);
   }
}        

运行结果
在这里插入图片描述

对于public有参构造来说

public class ReflecCreateInstance {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        //1.先获取到User类的Class对象
        Class<?> userClass = Class.forName("Reflection.User");
    //3.通过public的有参构造器创建实例
        //3.1先得到对应的构造器
        Constructor<?> constructor = userClass.getConstructor(String.class);
        //3.2创建实例,并传入参数
        Object hsp = constructor.newInstance("hsp");
        System.out.println("hsp="+hsp);
   }
}        

运行结果:
在这里插入图片描述
那么问题来了,如果对于私有的构造器来说我们难道可以用同样的方法来创建实例吗
在这里插入图片描述
我们实验一下

public class ReflecCreateInstance {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
      //4.通过非public的有参构造器创建实例
        //4.1得到private的构造器对象
        Constructor<?> constructor1 = userClass.getDeclaredConstructor(int.class, String.class);
        //4.2创建实例
        Object user2 = constructor1.newInstance(100, "张三丰");
        System.out.println(user2);
    }
}

运行结果
在这里插入图片描述
可以看出来虽然我们获得了这个私有的构造器,但却因为私有的原因,没有 办法来给它注入属性,实现实例的创建
那么怎么样来打破这种僵持的局面呢
在这里插入图片描述
在这里插入图片描述
我们可以在创建实例的时候将获得的私有构造器调用该方法,这个方法可以将我们的私有爆破掉,直接调用该构造器,就好比一个炸弹一样,将我们私有的锁炸开,这也就时你我们叫爆破的原因


反射爆破操作属性

假设我们现在有一个实体类

class Student{
    public int age;
    private static String name;

    public Student(){//构造器

    }

    @Override
    public String toString() {
        return "Student{" +
                "age=" + age +",name="+name+
                '}';
    }
}

操作共有属性

public class ReflecAccessProperty {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        //1.得到Student类对应的 Class对象
        Class<?> stuClass = Class.forName("Reflection.Student");
        //2.创建对象
        Object o = stuClass.newInstance();//o的运行类型就是Student
        System.out.println(o.getClass());
        //3.使用反射得到age,属性对象
        Field age = stuClass.getField("age");
        age.set(o,88);
        System.out.println(o);
        System.out.println(age.get(o));//得到age属性的值
 }
}

运行结果
在这里插入图片描述
操作私有属性

public class ReflecAccessProperty {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
        //1.得到Student类对应的 Class对象
        Class<?> stuClass = Class.forName("Reflection.Student");
      //4.使用反射操作name属性
        Field name = stuClass.getDeclaredField("name");
        //对name 进行爆破
        name.setAccessible(true);
        name.set(null,"杨宸");
        System.out.println(o);
        System.out.println(name.get(null));//获取属性值,要求name是static
        System.out.println(name.get(o));//获取属性值
    }
}

运行结果
在这里插入图片描述

反射爆破操作方法

假设现在有一个实体类

class Boss{//类
    public int age;
    private static String name;

    public Boss(){//构造器

    }
    private static String say(int n,String s,char c){
        return n + " "+s+" "+c;
    }
    public void hi(String s){//普通public方法
        System.out.println("hi"+s);
    }
}

操作共有方法

public class ReflectAccessMethod {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        //1.得到Boss类对应的Class对象
        Class<?> bossCls = Class.forName("Reflection.Boss");
        //创建对象
        Object o = bossCls.newInstance();
        //调用public的hi方法
        Method hi = bossCls.getMethod("hi",String.class);
        //Method hi = bossCls.getDeclaredMethod("hi");
        //调用
        hi.invoke(o, "杨宸");
            }
}

运行结果
在这里插入图片描述
操作私有方法

public class ReflectAccessMethod {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {

       //调用private static方法
        //4.1得到say方法对象
        Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);
        //4.2因为say方法时private,所以需要爆破,原理和前面讲的构造器和属性一样
        say.setAccessible(true);
        System.out.println(say.invoke(o,100,"张三",'男'));
    }
}

运行结果
在这里插入图片描述
在这里插入图片描述

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杨宸杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值