简体   繁体   English

如何在运行中从类定义中删除方法?

[英]How can I remove a method from the class definition on the fly?

Let me start by saying that this is purely an exercise to satisfy my curiosity. 首先让我说这纯粹是一种满足我好奇心的练习。 This is not meant to be used in any sort of production environment. 这并不意味着在任何类型的生产环境中使用。

What I would like to know is if it is in any way possible to redefine a class on the fly by removing/adding methods to its definition. 我想知道的是,通过删除/添加方法到其定义,是否可以通过任何方式重新定义类。

For example, given this class: 例如,给定此类:

public class PersonBuilder {

    private String name;
    private int age;

    public PersonBuilder name(String name) {
        this.name = name;
        System.out.println("Name defined");
        return this;
    }

    public PersonBuilder age(int age) {
        this.age = age;
        System.out.println("Age defined");
        return this;
    }

}

What I want is to completely remove name from the class definition once it is invoked. 我想要的是在调用后从类定义中完全删除name Equivalent behavior is expected if I invoke age . 如果我调用age则期望等效行为。 Basically whichever method is invoked gets removed. 基本上,无论调用哪种方法都会被删除。

I understand this would require some level of bytecode manipulation, I'm fairly certain it cannot be achieved via reflection. 我知道这需要一定程度的字节码操作,我相当肯定它不能通过反射来实现。

Anyway, I am looking for some guidance on how I could develop such behavior. 无论如何,我正在寻找关于如何发展这种行为的一些指导。 Any tips will be very helpful. 任何提示都会非常有帮助。

The problem is that even you find a way to do what you want (it is certainly possible) the code that call that methods is already compiled. 问题是即使你找到了一种方法来做你想要的(当然可能)调用那些方法的代码已经编译完成了。 This mean only practical outcome will be NoMethodDefFound exception at moment when method will be called second time. 这意味着只有当第二次调用方法时,实际结果才会是NoMethodDefFound异常。

So my solution is to create counter for method and check it each time you call this method. 所以我的解决方案是为方法创建计数器,并在每次调用此方法时检查它。 Throw exception when you called second time. 第二次打电话时抛出异常。

Of course this will not work with reflection. 当然,这不适用于反思。

Maybe you could use some wrapper or proxy that throws an exception once method is invoked. 也许你可以使用一些在调用方法时抛出异常的包装器或代理。

Or Method.setAccessible(false); 或Method.setAccessible(false);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM