这不是使用 Kotlins class 委托引用原始对象

This not referring to the original object using Kotlins class delegation

我对委托在 Kotlin 中的工作方式感到困惑。 Wikipedia 说:

With language-level support for delegation, this is done implicitly by having self in the delegate refer to the original (sending) object, not the delegate (receiving object).

给定以下代码:

interface BaseInterface {
    fun print()
}

open class Base() : BaseInterface {
    override fun print() { println(this) }
}

class Forwarded()  {
    private val base = Base()

    fun print() { base.print() }
}

class Inherited() : Base() {}

class Delegated(delegate: BaseInterface) : BaseInterface by delegate

fun main(args: Array<String>) {
    print("Forwarded: ")
    Forwarded().print();
    print("Inherited: ")
    Inherited().print();
    print("Delegated: ")
    Delegated(Base()).print();
}

我得到这个输出:

Forwarded: Base@7440e464
Inherited: Inherited@49476842
Delegated: Base@78308db1

我希望委托给 return Delegated 因为 self/this 应该引用原始对象。是我理解错了还是 Kotlin 委托不同?

Kotlin delegation 非常简单 - 它生成所有接口方法并在委托对象上隐式调用它,用户显式覆盖的方法除外。

您的示例在功能上与以下内容相同:

class Delegated(delegate: BaseInterface) : BaseInterface{
    // when generating bytecode kotlin assigns delegate object to internal final variable
    // that is not visible at compile time
    private val d = delegate

    override fun print(){
        d.print()
    }
}

所以很清楚为什么它打印 Base.

我认为如果我们查看编译成的反编译 Java 字节码,这最容易理解:

You can do this by going to Tools > Kotlin > Show Kotlin Bytecode and then clicking Decompile

public final class Delegated implements BaseInterface {
   // $FF: synthetic field
   private final BaseInterface $$delegate_0;

   public Delegated(@NotNull BaseInterface delegate) {
      Intrinsics.checkParameterIsNotNull(delegate, "delegate");
      super();
      this.$$delegate_0 = delegate;
   }

   public void print() {
      this.$$delegate_0.print();
   }
}

因此,当您执行 接口委托 时,Kotlin 会为名为 $$delegate_0 的委托创建字段,并在您的 delegating class 将在 $$delegate_0 上运行。您也可以有多个代表,他们将拥有自己的领域。不过有一点需要注意:您无法直接访问 $$delegate_0,即使您将其设为 var 也是如此:

class Delegated(var delegate: BaseInterface) : BaseInterface by delegate

这将编译为:

public final class Delegated implements BaseInterface {
   @NotNull
   private BaseInterface delegate;
   // $FF: synthetic field
   private final BaseInterface $$delegate_0;

   @NotNull
   public final BaseInterface getDelegate() {
      return this.delegate;
   }

   public final void setDelegate(@NotNull BaseInterface var1) {
      Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
      this.delegate = var1;
   }

   public Delegated(@NotNull BaseInterface delegate) {
      Intrinsics.checkParameterIsNotNull(delegate, "delegate");
      super();
      this.$$delegate_0 = delegate;
      this.delegate = delegate;
   }

   public void print() {
      this.$$delegate_0.print();
   }
}

伤心。我已经写过关于这个主题的文章 here