首页 文章

Kotlin嵌套成员的可见性

提问于
浏览
2

我有一个嵌套的私有类 . 我有一个 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,adders,vals等的构建器,然后在 init 中我构造了一个不可变的 Example .

我看到的唯一选择是:

  • 而不是在我的构建器中有 SneakyType ,保存构造一个所需的所有信息,然后在 Example 中构造它 . 工作,但增加了大量的复杂性 .

  • 放弃 Example 是不可变的,并允许构建器调用它来设置 Sneaky

  • 公开 Sneaky

有没有办法模仿Java版本?

1 回答

  • 2

    我看到两个可行的选择:

    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编译模块中可见 .

    • 使 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)
            }
        }
    }
    

相关问题