我不知道该如何在标题中措辞。 Kotlin相当于Java代码。我所有的尝试都以错误或stackoverflow结尾。与杰克逊进行序列化时会发生这种情况。
public class Test {
private String test1;
private String test2;
public String getTest1() {
return test1;
}
public void setTest1(String test1) {
this.test1 = test1;
}
public String getTest2() {
return test2!=null? test2:test1;
}
public void setTest2(String test2) {
this.test2 = test2;
}
}
下面的Kotlin代码
class Test(var test1: String? = "") {
var test2: String?
get() = if (StringUtils.isNotEmpty(test2)) test2 else test1
set(test2Val) {
test2 = test2Val
}
}
我缺少什么Kotlin基础知识?
答案 0 :(得分:2)
test2
最终将调用getter。您可以查看生成的Java代码以供参考。
在自定义getter和setter中,使用field
代替。因此正确的代码将是:
class Test(var test1: String? = "") {
var test2: String?
get() = if (StringUtils.isNotEmpty(field)) field else test1
set(test2Val) {
field = test2Val
}
}
注意:这会引起第二个问题。您尚未初始化变量,而该变量与vars有关。如果您有一个val
和一个自定义的getter返回其他值(即val x = ... get() = someOtherVar
,则不会产生编译器错误)。不过,这不适用于var
。但是,根据您的情况,使用= null
(或选择= ""
)就足够了。
但是,由于您说得到的是StackOverflowErrors而不是与缺少初始化有关的错误,所以我猜您实际上是在初始化它,只是没有将其包括在MCVE中。但是,如果您没有这样做,那么值得注意。
此外,Kotlin具有类似isNotEmpty()
和isNotBlank()
的方法,它们代替了对StringUtils.isNotEmpty()
的需要,并被称为field.isNotEmpty()
。请注意,这里您想做if(field?.isNotEmpty() == true) ...
,因为您最终会得到一个可为空的布尔值。这也意味着如果field为null或为空,则返回test1。如果需要,您还可以添加isNotBlank
。
如果设置器的功能与生成的设置器完全相同,则无需手动声明它们。如果执行此操作,类似IntelliJ的IDE也会警告您,并建议您删除它。手动声明它是否是默认设置程序并不重要,但是它可以帮助您减少代码编写。
答案 1 :(得分:1)
class Test(var test1: String? = "") {
var test2: String?
get() = if (StringUtils.isNotEmpty(test2)) test2 else test1
set(test2Val) {
test2 = test2Val // here you are recursively setting the value of test2
}
}
如果要将值分配给backing field,则应为
field = test2Val
但是,在这种情况下,setter将毫无意义,因为如果不声明它,它将具有相同的行为。
这个想法是field
是私有财产,get
和set
是设置者。然后,您可以选择从getter返回什么,以及如何处理传递给setter的值。
另一个问题是test2
需要一个初始值,在Java中它将默认初始化为null
,但是在Kotlin中,您必须显式分配一个初始值。例如,使用空字符串:
class Test(var test1: String? = "") {
var test2: String? = ""
get() = if (StringUtils.isNotEmpty(test2)) test2 else test1
}