安卓逆向基础知识:Java中的反射调用

Class类是反射的基石,Class是一个类,封装了当前对象所对应类的信息。

此处新建一个安卓项目,新建一个MysteryBox类:
在这里插入图片描述MysteryBox类代码如下:

package com.example.studyfour;

import java.util.Random;

public class MysteryBox {
    private final String content;
    private boolean isOpened;
    public final int price;
    private final String brand;

    public MysteryBox(){  //无参的构造函数
        this.price = 10;
        this.brand = "手办盲盒";

        isOpened = false;
        int random = new Random().nextInt();
        if (random % 100 == 1) {
            content = "隐藏款";
        } else {
            content = "普通款";
        }
    }

    private MysteryBox(String brand){   //有一个参数的构造函数
        this.brand = brand;
        this.price = 10;

        isOpened = false;
        int random = new Random().nextInt();
        if (random % 100 == 1) {
            content = "隐藏款";
        } else {
            content = "普通款";
        }
    }

    public MysteryBox(int price){  //有一个参数的构造函数
        this.brand = "手办盲盒";
        this.price = price;

        isOpened = false;
        int random = new Random().nextInt();
        int p = 100;
        if (price > 100) {
            p = 10;
        }
        if (random % p == 1) {
            content = "隐藏款";
        } else {
            content = "普通款";
        }
    }

    public  MysteryBox(int price ,String brand){   //有两个个参数的构造函数
        this.brand = brand;
        this.price = price;

        isOpened = false;
        int random = new Random().nextInt();
        int p = 100;
        if (price > 100) {
            p = 10;
        }
        if (random % p == 1) {
            content = "隐藏款";
        } else {
            content = "普通款";
        }
    }

    public void open(){
        isOpened = true;
    }

    private void close(){
        isOpened = false;
    }

    public String getContent() {
        if (isOpened){
            return content;
        }
        return "这个盲盒没有打开";
    }
}

在此处可以进行测试,无需编译app并安装在手机上:
在这里插入图片描述
输出结果:
在这里插入图片描述

获取Class对象的方法

  1. 通过类名获取 类名.class
  2. 通过对象获取 对象.getClass()
  3. 通过全类名获取 Class.fromName(全类名) 或者 classLoader.loadClass(全类名)
    @Test
    public void getClassDemo() throws ClassNotFoundException {
        //通过类直接获取
        Class<?> class1 = MysteryBox.class;
        System.out.println(class1);
        //通过对象获取class实例
        MysteryBox box = new MysteryBox();
        Class <? extends MysteryBox> aClass = box.getClass();
        System.out.println(aClass);
        //全类名获取
        Class <?> aClass1 = Class.forName("com.example.studyfour.MysteryBox");
        System.out.println(aClass1);
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        Class <?> aClass2 = systemClassLoader.loadClass("com.example.studyfour.MysteryBox");
        System.out.println(aClass2);
    }

如何判断是否为某个类的实例

⼀般情况下,使⽤ instanceof 关键字来判断是否为某个类的实例。
在这里插入图片描述

    @Test
    public void checkInstanceOf(){
        MysteryBox box = new MysteryBox();
        //instanceOf关键字
        System.out.println(box instanceof MysteryBox);
        //class.isInstance
        System.out.println(MysteryBox.class.isInstance(box));
        //isAssignableFrom
        System.out.println(box.getClass().isAssignableFrom(MysteryBox.class));
    }

创建实例

  1. 使⽤Class对象的newInstance()⽅法来创建Class对象对应类的实例。
  2. 先通过Class对象获取指定的Constructor对象,再调⽤Constructor对象的newInstance()⽅法来创建 实例。这 种⽅法可以⽤指定的构造器构造类的实例。
    @Test
    public void createInstance() throws Exception{
        Class<?> mysteryBoxClass = MysteryBox.class;
        //1.newInstance
        MysteryBox box1 = (MysteryBox) mysteryBoxClass.newInstance();
        System.out.println(box1.getContent());
        //2.首先获取到构造器,然后实例化类实例
        Constructor<?> constructor = mysteryBoxClass.getConstructor();
        Object box2 = constructor.newInstance();
        System.out.println(box2);
    }

输出结果:
在这里插入图片描述

获取构造器信息

  1. Constructor getConstructor(Class<?>… parameterTypes)
  2. Constructor[] getConstructors()
  3. Constructor getDeclaredConstructor(Class<?>… parameterTypes)
  4. Constructor[] getDeclaredConstructors()
    @Test
    public void getConstructor() throws Exception{
        //1.getConstructor
        Constructor<?> constructor = MysteryBox.class.getConstructor(int.class);
        System.out.println(constructor);
        //2.getConstructors 获取所有的构造函数,private修饰的构造方法无法获取到
        Constructor<?>[] constructors = MysteryBox.class.getConstructors();
        System.out.println(Arrays.toString(constructors));
        //3.获取private修饰的构造函数
        Constructor<?> declaredConstructor = MysteryBox.class.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor);
        //4.获取所有的构造函数
        Constructor<?>[] declaredConstructors = MysteryBox.class.getDeclaredConstructors();
        System.out.println(Arrays.toString(declaredConstructors));
    }

输出结果:
在这里插入图片描述

获取类的成员变量

  1. Field getField(String name)
  2. Field[] getFields()
  3. Field getDeclaredField(String name)
  4. Field[] getDeclaredFields()
    @Test
    public void getFields() throws Exception {
        MysteryBox box = new MysteryBox();
        Field priceField = MysteryBox.class.getField("price");   //此处也只能拿到public修饰的属性
        System.out.println(priceField.get(box));

        Field[] fields = MysteryBox.class.getFields();
        for (Field field: fields){
            System.out.println(field.getName() + "," + field.get(box));
        }

        //获取private修饰的属性
        Field content = MysteryBox.class.getDeclaredField("content");
        content.setAccessible(true); //对于private属性我们无法直接访问,在下面content.get处会触发异常,如果想要访问则需要添加一个accessible的属性
        System.out.println(box.getContent());
        System.out.println(content.get(box));

        Field[] declaredFields = MysteryBox.class.getDeclaredFields();
        for (Field declaredField: declaredFields){
            declaredField.setAccessible(true);
            System.out.println(declaredField.getName() + "," + declaredField.get(box));
        }
    }

输出结果:
在这里插入图片描述

获取方法

  1. Method getMethod(String name, Class[] params)
  2. Method[] getMethods()
  3. Method getDeclaredMethod(String name, Class[] params)
  4. Method[] getDeclaredMethods()
    @Test
    public void getMethods() throws Exception{
        MysteryBox box = new MysteryBox();
        //获取public修饰的方法
        Method getContent = MysteryBox.class.getMethod("getContent");
        Object content = getContent.invoke(box);   //主动调用getContent方法
        System.out.println(content);

        Method[] methods = MysteryBox.class.getMethods();
        for (Method method:methods){
            System.out.println(method);   //打印中没有private修饰的方法
        }

        box.open();
        System.out.println(box.getContent());

        Method close = MysteryBox.class.getDeclaredMethod("close");
        close.setAccessible(true);
        close.invoke(box);
        System.out.println(box.getContent());

        Method[] declareMethods = MysteryBox.class.getDeclaredMethods();  //拿到所有的方法,包括private
        for (Method method:declareMethods){
            System.out.println(method);   
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值