为了账号安全,请及时绑定邮箱和手机立即绑定

使用字节好友对具有强制转换的参数调用方法

使用字节好友对具有强制转换的参数调用方法

翻翻过去那场雪 2022-09-22 10:25:58

我对Byte Buddy非常陌生,我正在尝试使用它来创建在对象上执行getter方法的接口的实现。我的界面看起来像这样:


public interface Executor {

    Object execute(final Object target);

}

这个想法是,如果我有一个类,如:


public class User {

   ...

   public String getName() { return this.name; }

   public String getSurname() { return this.surname; }

}

我需要能够创建一个接口的实现,该方法假设是一个并调用它,然后是另一个对 执行相同操作的实现,依此类推。因此,等效的 java 代码将是:Executorexecute(obj)objUsergetName()getSurname()


public class MyHypotheticalByteBuddyExecutorImpl implements Executor {

    @Override

    Object execute(final Object target) {

        return ((User) target).getName();

    }

}

因此,我们的想法是能够为类 + getter 的任意组合创建如上所示的类,就像在本例中 + .UsergetName()


我(认为我)知道如何让Byte Buddy创建一个几乎做到这一点的类:


final Method nameMethod = User.class.getMethod("getName", null);


final Class<?> myHypotheticalByteBuddyExecutorImpl =

    new ByteBuddy()

        .subclass(Object.class)

        .implement(Executor.class)

        .method(ElementMatchers.named("execute"))

            .intercept(MethodCall.invoke(nameMethod).onArgument(0))

        .make()

        .load(ByteBuddyTest.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)

        .getLoaded();

...但后来字节好友正确地抛出了一个异常,说我不能在 .因此,我假设我缺少演员阵容:getName()Object((User) target)


Exception in thread "main" java.lang.IllegalStateException: Cannot invoke public java.lang.String com.example.User.getName() on class java.lang.Object

    at net.bytebuddy.implementation.MethodCall$TargetHandler$ForMethodParameter$Resolved.toStackManipulation(MethodCall.java:2527)

    at net.bytebuddy.implementation.MethodCall$Appender.toStackManipulation(MethodCall.java:3541)

    at net.bytebuddy.implementation.MethodCall$Appender.apply(MethodCall.java:3502)

    ...

我相信这可以被定义为一个(我可能完全错了),就像这样:StackManipulation


final StackManipulation typeCasting =

    TypeCasting.to(TypeDescription.ForLoadedType.of(User.class));

但是,我无法在 Byte Buddy API 的任何地方找到如何在执行 getter 之前将此强制转换(或我可能需要强制转换的任何其他代码)应用于方法的参数。execute(Object)


我该如何实现这一点?


查看完整描述

1 回答

?
catspeake

TA贡献766条经验 获得超0个赞

这应该通过使用动态类型来工作,您可以通过以下方式进行配置:

MethodCall.invoke(nameMethod)
  .onArgument(0)
  .withAssigner(Assigner.DEFAULT, Assigner.Typing.DYNAMIC);

堆栈操作用于创建自定义字节代码,我不认为这是您要在此处执行的操作。


查看完整回答
反对 回复 2022-09-22

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信