栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

安卓逆向基础知识: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  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);   
        }
    }
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/851321.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号