【问题标题】:Subclass an abstract parameterized class with byte-buddy使用 byte-buddy 子类化抽象参数化类
【发布时间】:2015-09-23 13:51:19
【问题描述】:

我从 byte-buddy 开始,这是一个非常令人印象深刻的字节码操作库。它工作正常,但我对抽象的参数化类进行子类化时遇到问题:

public interface Task<DTO extends IDatabaseObject> {

  void execute(DTO input);

  Class<DTO> getDataObjectClass();
}

这是抽象类:

public abstract class AbstractTask<T extends IDatabaseObject> implements Task<T> {

  protected Class<T> dataObjectClass = /* Call to an external method which retrieves the class from T */;

  @Override
  public Class<T> getDataObjectClass() {
    return dataObjectClass;
  }
}

我想创建一个扩展的具体类

public abstract class AbstractTask<T extends IDatabaseObject> implements Task<T> {

  protected String SUCCESS_MESSAGE_PREFIX = "task.mess.";

  protected Class<T> dataObjectClass;// = Introspector.getParameterizedTypeClass(this, AbstractTask.class, 0);

  @Override
  public Class<T> getDataObjectClass() {
    return dataObjectClass;
  }

  @Override
  public String getSuccessMessage(IDatabaseObject t) {
    final String messageKey = SUCCESS_MESSAGE_PREFIX + this.getClass().getSimpleName();
    final MessagesFactory messagesFactory = MessagesFactory.getInstance();
    return messagesFactory.isPresent(messageKey) ? messagesFactory.get(messageKey) : "";
  }
}

我想创建一个AbstractTask 的具体类,以完成以下断言:

createConcreteImplementation(Person.class).getDataObjectClass() == Person.class

createConcreteImplementation 方法通过 Byte Buddy 创建一个子类。即使这不可能,我也欢迎提供替代方法或近似此行为的建议。

【问题讨论】:

    标签: java bytecode byte-buddy


    【解决方案1】:

    Byte Buddy 目前不完全支持泛型类型。这是我目前正在使用的东西(我写了 Byte Buddy),我希望在今年的某个时候支持这个功能。

    但是,您始终可以覆盖 Byte Buddy 以覆盖 getDataObjectClass 方法,以便从该方法返回类,而不是使用字段的值:

    AbstractTask<?> createConcreteImplementation(Class<?> type)
      return new ByteBuddy()
        .subclass(AbstractTask.class)
        .method(named("getDataObjectClass"))
        .intercept(FixedValue.value(new TypeDescription.ForLoadedType(type))) // (*)
        .make()
        .load(type.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
        .getLoaded();
    }
    

    1 处的显式包装是必要的,因为下一个版本会消除一个错误:https://github.com/raphw/byte-buddy/pull/34#issuecomment-118888979

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多