嵌套成员的Kotlin可见性

我有一个嵌套的私人类的类。 我有一个Builder ,标准的Java构建器模式,构造这个类的实例。 我不希望我班以外的任何人能够看到我隐藏的课程。

在Java中,我可以这样做:

 public class Example { private SneakyType doNotExposeThis; private Example(Builder builder) { // OK 'cause in Java you can access the private // members of a nested class doNotExposeThis = builder.doNotExposeThis; } private static class SneakyType { SneakyType(String x) { // stuff } } public static class Builder { private SneakyType doNotExposeThis; public void addFoo(String something) { doNotExposeThis = new SneakyType(something); } public Example build() { return new Example(this); } } } 

但我不知道如何在Kotlin中做同样的事情:

 class Example(builder: Builder) { private lateinit var doNotExposeThis: SneakyType init { doNotExposeThis = builder.doNotExposeThis } class Builder { // If private or internal I can't access it in Example.init // and if public it gets exposed. val doNotExposeThis: SneakyType fun addFoo(something: String) { // actual construction is quite a bit more complex doNotExposeThis = SneakyType(something) } } } 

请注意,为了Java互操作性,我想保留我的构建器。 我也想要它,因为我的对象是复杂的构造,我希望它是不可变的,所以我有一个建设者有很多setter,加法器,vals等等,然后在init我构造一个单一的不可变的Example

我看到的唯一选择是:

  1. 而不是在我的建设者有一个SneakyType保存所有必要的信息来构造一个,然后在Example构造它。 工作,但增加了一大堆的复杂性。
  2. 放弃Example是不可改变的,并允许建设者调用它来建立一个Sneaky
  3. 暴露Sneaky

有没有办法模仿Java版本?

我看到两个可行的选择:

  1. 使用internal 可见性修改器 :

     class Example private constructor(builder: Builder) { private val doNotExposeThis: SneakyType init { doNotExposeThis = builder.doNotExposeThis } internal class SneakyType(x: String) class Builder { internal lateinit var doNotExposeThis: SneakyType fun addFoo(something: String) { doNotExposeThis = SneakyType(something) } fun build(): Example { return Example(this) } } } 

    这将使SneakyType只在你的Kotlin编译模块中可见。

  2. Example独立于其构建器(这是我推荐的):

     class Example private constructor(private val doNotExposeThis: SneakyType) { private class SneakyType(x: String) class Builder { private lateinit var doNotExposeThis: SneakyType fun addFoo(something: String) { doNotExposeThis = SneakyType(something) } fun build(): Example { return Example(doNotExposeThis) } } }