在Kotlin的建造者样式

我是kotlin世界的新手。 我有一个用Java编写的现有的构建器,并且想在我将这个项目迁移到Android中的kotlin时将其转换为Kotlin。 但是,Android Studio内置的工具似乎有一些错误,然后转换的代码是不可编译的。 这是显示无法访问我的UserBuilder类中的变量。

这是来自教程的Java代码

 public class Person { private final String firstName; // required private final String lastName; // required private final int age; // optional private final String phone; // optional private final String address; // optional private Person(UserBuilder builder) { this.firstName = builder.firstName; this.lastName = builder.lastName; this.age = builder.age; this.phone = builder.phone; this.address = builder.address; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } public String getPhone() { return phone; } public String getAddress() { return address; } public static class UserBuilder { private final String firstName; private final String lastName; private int age; private String phone; private String address; public UserBuilder(String firstName, String lastName) { this.firstName = firstName; this.lastName = lastName; } public UserBuilder age(int age) { this.age = age; return this; } public UserBuilder phone(String phone) { this.phone = phone; return this; } public UserBuilder address(String address) { this.address = address; return this; } public Person build() { return new Person(this); } } } 

自动转换的kotlin代码:

 class Person private constructor(builder: UserBuilder) { val firstName: String // required val lastName: String // required val age: Int // optional val phone: String // optional val address: String // optional init { //cannot access the variables, they are private in UserBuilder this.firstName = builder.firstName this.lastName = builder.lastName this.age = builder.age this.phone = builder.phone this.address = builder.address } class UserBuilder(private val firstName: String, private val lastName: String) { private var age: Int = 0 private var phone: String? = null private var address: String? = null fun age(age: Int): UserBuilder { this.age = age return this } fun phone(phone: String): UserBuilder { this.phone = phone return this } fun address(address: String): UserBuilder { this.address = address return this } fun build(): Person { return Person(this) } } } 

更新

 class Person private constructor(builder: UserBuilder) { val firstName: String // required val lastName: String // required val age: Int // optional val phone: String? // optional val address: String? // optional init { this.firstName = builder.firstName this.lastName = builder.lastName this.age = builder.age this.phone = builder.phone this.address = builder.address } class UserBuilder(internal val firstName: String, internal val lastName: String) { internal var age: Int = 0 internal var phone: String? = null internal var address: String? = null fun age(age: Int): UserBuilder { this.age = age return this } fun phone(phone: String): UserBuilder { this.phone = phone return this } fun address(address: String): UserBuilder { this.address = address return this } fun build(): Person { return Person(this) } } } 

鉴于它是Kotlin,使用数据类实际上可以使这变得更简单。

 data class User(val firstName: String, val lastName: String, val age: Int = 0, val phone: String? = null, val address: String? = null) 

而就是这样! 前两个参数是必需的,但是如果你想指定更多的参数,你只需要指定它们的名字:

 val user = User("John", "Doe", phone = "555-1212") 

没有建设者需要!

就像以前一样做简单的转换。

现在你会看到, UserBuilder将有internal访问修改器只是删除这个并添加公共或任何您的要求是。


EDIT1

好的, internal关键字不存在于你的Kotlin代码中,我忽略了检查你的代码。

所以现在你需要做的是在Person类中创建一个对象,并把你的UserBuilder类放在那里。

检查以下代码:

 class Person private constructor(builder: Builder.UserBuilder) { val firstName: String // required val lastName: String // required val age: Int // optional val phone: String // optional val address: String // optional init { //cannot access the variables, they are private in UserBuilder this.firstName = builder.firstName this.lastName = builder.lastName this.age = builder.age this.phone = builder.phone this.address = builder.address } object Builder { class UserBuilder(private val firstName: String, private val lastName: String) { private var age: Int = 0 private var phone: String? = null private var address: String? = null fun age(age: Int): UserBuilder { this.age = age return this } fun phone(phone: String): UserBuilder { this.phone = phone return this } fun address(address: String): UserBuilder { this.address = address return this } fun build(): Person { return Person(this) } } } } 

这应该像你的Java代码一样工作。

希望它有帮助。

 class Person private constructor(builder: UserBuilder) { val firstName: String // required val lastName: String // required val age: Int // optional val phone: String // optional val address: String // optional init { this.firstName = builder.firstName this.lastName = builder.lastName this.age = builder.age this.phone = builder.phone this.address = builder.address } class UserBuilder(private val _firstName: String, private val _lastName: String) { private var _age: Int = 0 private var _phone: String? = null private var _address: String? = null var firstName: String get() = this._firstName var lastName: String get() = this._lastName var age: Int = 0 get() = this._age var phone: String? = null get() = this._phone var address: String? = null get() = this._address fun age(age: Int): UserBuilder { this._age = age return this } fun phone(phone: String): UserBuilder { this._phone = phone return this } fun address(address: String): UserBuilder { this._address = address return this } fun build(): Person { return Person(this) } } 

}

以这种方式使用自定义getter可以解决私人访问修饰符问题。