Java 字段和cast-in Bytebuddy上的方法委派

Java 字段和cast-in Bytebuddy上的方法委派,java,byte-buddy,Java,Byte Buddy,使用Bytebuddy时,假设以下情况: class Service { protected Handler handler; ... } interface Handler { public void handle(); } class ConcreteHandler implements Handler { public void handle() { ... } public void handle2() { ...

使用Bytebuddy时,假设以下情况:

class Service {
    protected Handler handler;
...
}

interface Handler {
   public void handle();
}

class ConcreteHandler implements Handler {
    public void handle() {
       ...
    }
    public void handle2() {
       ...
    }
}
通常我们调用Handler的handle方法,但在某些情况下,我们需要调用ConcreteHandler类的handle2,即在运行时调用它。现在的问题是:这是否可能使用Bytebuddy?可能是的,但是怎么做呢

我试过:

if (condition) {
    MethodCall methodCall = (MethodCall) 
        MethodCall.invoke(methodHandle2).onField("handler")
                        .withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC);
}
。。。但它失败了,出现了一个非法状态异常:无法调用public void com.framework.ConcreteHandler.handle2。。。在受保护的com.framework.Handler上com.framework.Service.Handler


有什么想法吗?

如果您的字段变量是一个处理程序,您不能调用handle2,因为处理程序不知道handle2方法

为了为有效类调用handle2方法,需要将处理程序强制转换为ConcreteHandler,这一过程称为向下转换,因为您将实例强制转换为对象层次结构中较低的对象。只有当处理程序实例实际上是一个具体的处理程序而不是处理程序的其他派生时,这才有效

例如:

ConcreteHandler的if-handler实例{ ConcreteHandler=ConcreteHandler; 1.handle2; } 编辑: 我开始工作的一次性重定向。我不完全确定如何将其作为文档中的永久重定向工作,但如果您想要永久重定向该方法,则重新定义似乎会起作用。为了使类ConcreteHandler、Handler等成为公共类,还需要对源代码进行更改

新ByteBuddy .子条款ConcreteHandler.class .methodnamedhandle.interceptMethodDelegation.toConcreteHandler.class 制作 .loadgetClass.getClassLoader .getLoaded .新实例 .handle2;
如果字段变量是处理程序,则不能调用handle2,因为处理程序不知道handle2方法

为了为有效类调用handle2方法,需要将处理程序强制转换为ConcreteHandler,这一过程称为向下转换,因为您将实例强制转换为对象层次结构中较低的对象。只有当处理程序实例实际上是一个具体的处理程序而不是处理程序的其他派生时,这才有效

例如:

ConcreteHandler的if-handler实例{ ConcreteHandler=ConcreteHandler; 1.handle2; } 编辑: 我开始工作的一次性重定向。我不完全确定如何将其作为文档中的永久重定向工作,但如果您想要永久重定向该方法,则重新定义似乎会起作用。为了使类ConcreteHandler、Handler等成为公共类,还需要对源代码进行更改

新ByteBuddy .子条款ConcreteHandler.class .methodnamedhandle.interceptMethodDelegation.toConcreteHandler.class 制作 .loadgetClass.getClassLoader .getLoaded .新实例 .handle2;

这似乎是Byte Buddy中的一个bug。我希望修复了该问题,该问题将在Byte Buddy 1.10.14中解决。您可以同时尝试快照。

这似乎是Byte Buddy中的一个错误。我希望修复了该问题,该问题将在Byte Buddy 1.10.14中解决。您可以同时尝试快照。

我很感谢您的回答,但这个问题是在使用ByteBuddy时提出的。这个演员必须用Bytebuddy的描述语言进行……啊,我的错!您是否尝试过这里的代表团示例:-我将尝试一下。如果我有机会的话,我会回来的,luckI试过了,并设法重新接通了电话,但只是作为一个一次性的,而不是永久性的。我看作者已经给出了答案。这是一个有趣的项目,不是我以前遇到过的项目,所以谢谢你的问题:我感谢你的回答,但是这个问题是在使用ByteBuddy的上下文中提出的。这个演员必须用Bytebuddy的描述语言进行……啊,我的错!您是否尝试过这里的代表团示例:-我将尝试一下。如果我有机会的话,我会回来的,luckI试过了,并设法重新接通了电话,但只是作为一个一次性的,而不是永久性的。我看作者已经给出了答案。这是一个有趣的项目,不是我以前遇到过的,所以谢谢你的问题:谢谢你的努力。这在内部是什么?一般来说,它听起来非常合适……它检查一个方法是否可以在给定类型上调用,而子类型方法是否可以在其超类型上调用。因此,检查不适用,因为它没有考虑铸件。明白。在提交过程中,你已经弱化了检查,以便进行铸造,对吗?是的。就是这样。我可以确认这是ByteBuddy中的一个问题,而在2020-07-16从源代码构建的B1.10.14-SNAPSHOT修复了它。谢谢,@RafaelWinterhalter的快速修复。谢谢你的努力。你怎么办
在内部是不允许的吗?一般来说,它听起来非常合适……它检查一个方法是否可以在给定类型上调用,而子类型方法是否可以在其超类型上调用。因此,检查不适用,因为它没有考虑铸件。明白。在提交过程中,你已经弱化了检查,以便进行铸造,对吗?是的。就是这样。我可以确认这是ByteBuddy中的一个问题,而在2020-07-16从源代码构建的B1.10.14-SNAPSHOT修复了它。谢谢,@RafaelWinterhalter的快速修复。