Hello,
I am trying to implement some Spotbugs suggestions on my kotlin code. Spotbugs complains that my code may expose internal representation by returning reference to mutable object (EI_EXPOSE_REP) on a java.util.Date field. Same issue with EI_EXPOSE_REP2.
I fixed it by providing my own implementation for the accessors and mutators:
var creationDate: Date = Date()
set(value) {
field = Date(value.getTime())
}
get() = Date(creationDate.getTime())
However after this change Spotbugs now complains about the IL_INFINITE_RECURSIVE_LOOP: This method unconditionally invokes itself. This would seem to indicate an infinite recursive loop that will result in a stack overflow.
And it is true. If I look at the bytecode kotlin has generated I can see that it uses invokevirtual whereas the bytecode generated by the java compiler uses getfield instead.
I am using OpenJDK 11 for the java compilation. For Kotlin I am using Kotlin 1.3.50.
OpenJDK11 bytecode
dup
aload0 // reference to self
getfield a/b/c/d/BlogArticle2.creationDate:java.util.Date
invokevirtual java/util/Date.getTime()J
invokespecial java/util/Date.<init>(J)V
areturn
Corresponding Java source code from decompilation of the java compiled bytecode
public Date getCreationDate() {
return new Date(this.creationDate.getTime());
}
Kotlin 1.3.50 bytecode
dup
aload0 // reference to self
invokevirtual a/b/c/d/BlogArticle.getCreationDate()Ljava/util/Date;
invokevirtual java/util/Date.getTime()J
invokespecial java/util/Date.<init>(J)V
areturn
Corresponding java source code from decompilation of the kotlin compiled bytecode
public final Date getCreationDate() {
return new Date(this.getCreationDate().getTime());
}
As you can see the decompiled source code calls the method itself instead of the field (a result of the invokevirtual bytecode instruction). Any idea if (how) I can fix it? Is this an issue with Kotlin or am I doing something wrong?
Thank you