kotlin 如何重定现有类的基以删除它实现的某些接口

ryevplcw  于 2022-11-25  发布在  Kotlin
关注(0)|答案(2)|浏览(120)

朋友们,你能告诉我如何重定现有类的基,这样它就不会在它的父类中有特定的接口吗?
比如说

interface One {
  fun one(): Unit
}

interface Two {
 fun two(): Unit
}

class Test: One, Two {
  // implementation of one() and two()
}

val newClass = ByteBuddy()
    .rebase(Test::class.java)
    .name("com.test.Test2")
    .implement(Two::class.java)
    .make()
    .load(this.javaClass.classLoader, ClassLoadingStrategy.Default.WRAPPER)
    .loaded

val inst = newClass.declaredConstructors.first().newInstance()
val isOne = inst is One

不幸的是isOne仍然是真的,我错过了什么?

jv4diomz

jv4diomz1#

Byte Buddy并不是真的要删除属性,你可以通过访问方法使用ASM来删除字节码中的元素。
或者,您可以声明一个新类,按照您的方式定义它,并将其命名为与您要更改的类相同的名称。

g6baxovj

g6baxovj2#

我通过创建这样的委托类解决了这个问题

val fieldDelegate = "delegate"
val unloaded = ByteBuddy()
    .subclass(Any::class.java)
    .defineField(fieldDelegate, Test::class.java, Opcodes.ACC_PRIVATE or Opcodes.ACC_FINAL)
    .name(Test::class.java.canonicalName + "Wrapper")
    .implement(Two::class.java)
    .defineConstructor(Visibility.PUBLIC)
    .withParameters(Test::class.java)
    .intercept(MethodCall.invoke(Object::class.java.getConstructor()).andThen(FieldAccessor.ofField(fieldDelegate).setsArgumentAt(0)))
    .method(ElementMatchers.isAbstract())
    .intercept(MethodDelegation.toField(fieldDelegate))
    .make()

val clazz = unloaded
    .load(Test::class.java.classLoader, ClassLoadingStrategy.Default.WRAPPER)
    .loaded

相关问题