如何在运行时通过Java反射更改ATM类

4

有一个ATM GUI .class文件。

在ATM类中,如果用户点击刷卡,它将使用Java反射动态调用我的Card.class。

在ATM类中有这个变量:

int userBalanceField = 100;

我将尝试动态将其更改为Integer.MAX_VALUE。 以下是ATM中的滑动功能:
    Object object;
    Class class_ = null;
    ClassLoader classLoader;
    this.printToScreen("Loading Card");
    String string = "." + File.separator + "Card.class";
    File file = new File(string);
    ClassLoader classLoader2 = classLoader = ClassLoader.getSystemClassLoader();
    try {
        object = new URL("file:" + System.getProperty("user.dir") + File.separator + "Card.class");
        class_ = Card.class;

    }
    catch (MalformedURLException var6_7) {
        var6_7.printStackTrace();
    }
    object = "Card";

    this.printToScreen("Reading card data and verifying ATM");
    try {
        Method method = class_.getMethod("swipe", ATM.class);
        Data data = (Data)method.invoke(null, this);
        if (data == null) {
            this.printToScreen("Machine considered invalid");
        } else {
            this.user = data;
            this.tempEntry = "";
            this.screenState = 2;
            this.updateScreen();
        }
    }
    catch (SecurityException var8_11) {
        this.printToScreen("Security Exception when swiping card.");
    }
    catch (NoSuchMethodException var8_12) {
        this.printToScreen("No Such method exception when swiping card.");
    }
    catch (IllegalArgumentException var8_13) {
        this.printToScreen("Illegal Argument exception when swiping card.");
    }
    catch (IllegalAccessException var8_14) {
        this.printToScreen("Illegal Access exception when swiping card.");
    }
    catch (InvocationTargetException var8_15) {
        this.printToScreen("Invocation Target exception when swiping card.");
    }

这是我的尝试。
    public static ATM.Data swipe(ATM anATM){ 

    Class atmClass = anATM.getClass();
    try {
        Field moneyInMachineField = atmClass.getDeclaredField("moneyInMachine");
        System.out.println("Loading field..." + moneyInMachineField.getName());

        Field userBalanceField = atmClass.getDeclaredField("userBalance");
        userBalanceField.setAccessible(true);


        ATM.Data result = new ATM.Data(cardNumber, accountNumber, name, pinNumber);
        userBalanceField.set(result, Integer.MAX_VALUE);

        return result;
    } catch (IllegalAccessException 
            | NoSuchFieldException 
            | SecurityException e) {
        e.printStackTrace();
    }
    return null;
}

我在刷卡时一直收到“调用目标异常”错误信息。

3个回答

2
您正在使用的语法是用于创建新的非静态内部类。 DataATM 的静态内部类,因此您需要执行以下操作:
ATM.Data result = new ATM.Data(cardNumber, accountNumber, name, pinNumber);

根据Java文档
例如,要创建静态嵌套类的对象,请使用以下语法:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
如果Data是非静态的,则它将包含对ATM的特定引用(这将使其能够引用AMT.this.userBalance),但它仅用作POJO。
除此之外,您设置字段时不正确。调用field.set()时,您需要为其提供包含该字段的对象和要将其设置为的值。
在您的情况下,它应该是:
userBalanceField.set(anATM, Integer.MAX_VALUE);

查看Java文档,请点击此处

现在当刷卡时,ATM类会抛出运行时异常。 - user6270045
请问您能提供一下堆栈跟踪吗? - Ian2thedv
尝试使用 userBalanceField.set(anATM, Integer.MAX_VALUE); 这段代码,它会将对象 anATM 的 userBalanceField 设置为 Integer.MAX_VALUE。 - Ian2thedv
你是谁?你是个天才! - user6270045
@HuyVo 哈哈,我更新了答案,很高兴能帮到你 :) - Ian2thedv
显示剩余2条评论

0

代码

Field userBalanceField = atmClass.getDeclaredField("userBalance");

这段代码表明userBalanceATM的一个字段,但是

ATM.Data result = new ATM.Data(cardNumber, accountNumber, name, pinNumber);
userBalanceField.set(result, Integer.MAX_VALUE);

尝试设置ATM.Data对象的userBalance字段。

如果ATM.Data中存在userBalance字段,请尝试:

Field userBalanceField = ATM.Data.class.getDeclaredField("userBalance");

java.lang.NoSuchFieldException: userBalance - user6270045
userBalanceField 在自动取款机中。 - user6270045

0

InvocationTargetException包装了被反射方法抛出的所有异常。这是因为Reflection API无法感知方法可能引发的异常类型。

尝试捕获:

InvocationTargetException

然后使用:

getCause();

例如:

catch (InvocationTargetException e) {
     System.out.println(e.getCause();
}

这将告诉您实际出了什么问题。它还将帮助我们调试您的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接