【问题标题】:Debugging dynamic proxy creation mutates invocationhandler state调试动态代理创建会改变调用处理程序状态
【发布时间】:2020-01-11 21:54:14
【问题描述】:

假设以下动态 java 代理具有调用处理程序,该处理程序具有在调用期间更改的内部状态:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args) {
        Test test = (Test) Proxy.newProxyInstance(
                Test.class.getClassLoader(),
                new Class[] { Test.class },
                new MyInvocationHandler(true));
        test.doWork();
        test.doWork();
    }

    public interface Test {
        void doWork();
    }

    public static class MyInvocationHandler implements InvocationHandler {
        private boolean flag;
        public MyInvocationHandler(boolean flag) {
            this.flag = flag;
        }
        @Override
        public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
            if ("doWork".equals(method.getName())) {
                System.out.println("Flag is " + flag);
            }
            if (flag) {
                flag = false;
                // Do somemthing
            }
            return null;
        }
    }
}

我希望这会将以下内容写入标准输出:

标志为真

标志为假

但是在一步步调试的时候,会输出:

标志为假

标志为假

我正在使用 Java 11.0.5 和 IntelliJ IDEA 进行调试。

有人知道这里发生了什么吗?

【问题讨论】:

    标签: java debugging intellij-idea dynamic-proxy


    【解决方案1】:

    'toString()' 对象视图 选项已知会在调试期间引起副作用,因为它会调用在正常应用程序执行期间未调用的方法。如果你的应用状态依赖于这些方法,你应该禁用相应的选项(File | Settings | Build, Execution, Deployment | Debugger | Data Views | Java: 启用 'toString()' 对象视图):

    【讨论】:

    • 是的,确实是调试器调用了 toString 方法。将突变子句的保护更改为if (!"toString".equals(method.getName()) && flag) { 也可以。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 2012-06-22
    相关资源
    最近更新 更多