【问题标题】:Dynamically mirroring class and adding constructor动态镜像类并添加构造函数
【发布时间】:2015-01-10 21:12:26
【问题描述】:

我有一个没有任何显式构造函数的具有默认可见性的类。我想生成类似的类(具有相同的方法和注释),但具有显式的公共默认构造函数。有可能以简单的方式吗?任何准备好使用代理框架?恐怕用 cglib 手动完成会是相当大的任务

【问题讨论】:

  • 我动态需要它。我有一个类作为输入
  • 然后是 cglib。这不是一项大任务。只是丑陋。
  • 无论如何编译器都会为你生成一个构造函数。在字节码层面,没有区别。
  • true 但非公共类的隐式构造函数在Class.getConstructors() 中不可见。我需要创建一个具有从此方法返回的无参数构造函数的类

标签: java proxy bytecode java-bytecode-asm cglib


【解决方案1】:

cglib 将始终覆盖方法而不复制注释。 cglib 中不支持注解,因为它是在 Java 5 出现之前编写的。

如果您愿意使用与 cglib 不同的库,请查看我的库 Byte Buddy 以定义此类构造函数。使用它,您可以定义一个 Java 代理来增加原始类的可见性,也可以创建一个子类来指示保留库。

一个子类会按如下方式生成:

DynamicType.Builder<? extends Foo> builder = new ByteBuddy()
  .subclass(Foo.class, ConstructorStrategy.Default.NO_CONSTRUCTORS)
  .modifiers(() -> return Foo.class.getModifiers() | Modifiers.PUBLIC);
Foo.class.getDeclaredConstructors().forEach( c ->
  DynamicType.Builder.MethodAnnotationTarget<? extends Foo> target = builder
      .defineConstructor(Arrays.asList(c.getParamaterTypes), 
                         () -> return c.getModifiers() | Modifiers.PUBLIC)
      .intercept(SuperMethodCall.INSTANCE)
      .annotateMethod(c.getAnnotations());
  int index = 0;
  for(Annotation[] a : c.getParameterAnnotatations()) {
    target = target.annotateParameter(index++, a);
  }
  builder = target;
)
Class<? extends Foo> subclass = builder.make()
  .load(Foo.class.getClassLoader(), ClassLoadingStrategy.Default.WRAPPER);

一开始这看起来像很多代码(我目前正在增强 API 以使其更短。但是您要做的是以下内容:

  1. 您定义了Foo 的新子类,并指示字节好友不要添加任何构造函数。
  2. 您将此类的修饰符定义为类似于 Foo 的修饰符,但另外是 public
  3. 您查找Foo 声明的所有构造函数,并为每个这样的构造函数定义一个新的构造函数,用于生成的子类。此构造函数定义了与Foo 的构造函数完全相同的参数类型,并且还复制了修饰符。此外,可见性设置为public
  4. 复制Foo 的构造函数的所有注解,使其出现在子类的构造函数中。
  5. 您对所有参数注释重复此操作。
  6. 您创建并加载类(在Foo 的类加载器上)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2020-11-28
    • 2020-08-26
    • 1970-01-01
    • 2011-05-22
    • 2011-10-07
    相关资源
    最近更新 更多