根据匿名对象访问限制器的实现方法

Implementation method according to the access limiter of anonymous object

当一个匿名对象是public时,它只是作为一个对象return实现,但是当它是private时,它是return类型-施放对象。看看下面的 Kotlin 代码。

private fun foo() = object {
    val x: String = "x"
}

fun bar() = object {
    val x: String = "x"
}

这段代码反编译成Java后,变成了这样:

private static final <undefinedtype> foo() {
    return (<undefinedtype>)(new Object() {
        @NotNull
        private final String x = "x";

        @NotNull
        public final String getX() {
            return this.x;
        }
    });
}

@NotNull
public static final Object bar() {
    return new Object() {
        @NotNull
        private final String x = "x";

        @NotNull
        public final String getX() {
            return this.x;
        }
    };
}

因此,当您尝试使用该代码时,只有 private 匿名对象可以访问 x

那么,为什么每个访问修饰符都有不同的实现?

这就是语言定义匿名对象语义的方式。

匿名对象的类型只能在声明范围内使用,当您使用 public 修饰符时,匿名对象会转义当前范围并转换为 Any (隐式超类型)。由于 Any 没有任何 属性 x,您无法访问它。 另一方面,当您使用 private 修饰符时,您要确保它不会超出当前范围。

来自Kotlin language specification

The main difference between a regular object declaration and an anonymous object is its type. The type of an anonymous object is a special kind of type which is usable (and visible) only in the scope where it is declared. It is similar to a type of a regular object declaration, but, as it cannot be used outside the declaring scope, has some interesting effects.

When a value of an anonymous object type escapes current scope:

  1. If the type has only one declared supertype, it is implicitly downcasted to this declared supertype;
  2. If the type has several declared supertypes, there must be an implicit or explicit cast to any suitable type visible outside the scope, otherwise it is a compile-time error.

Note: in this context “escaping current scope” is performed immediately if the corresponding value is declared as a non-private global or classifier-scope property, as those are parts of an externally accessible interface.