https://kotlinlang.org logo
Title
s

Sangmin Lee

04/12/2022, 2:51 AM
I’m wondering why Jvm Setter is not used in the code
@RestController
class TestController {
    @GetMapping("/test")
    fun test() {
        val data = TestData(bar = "first")
        data.bar = "second"
        data.setBar("third")
    }
}

data class TestData(
    @JvmField
    var bar: String
) {
    fun getBar() = bar
    fun setBar(value: String) {
        print("\nSetter is called! - value: $value\n")
        bar = value
    }
}
output:
Setter is called! - value: third
why
data.bar = "second"
doesn’t call setBar?
The below is Java decompiled from kotiln code.
public final class TestData {
   @JvmField
   @NotNull
   public String bar;

   @NotNull
   public final String getBar() {
      return this.bar;
   }

   public final void setBar(@NotNull String value) {
      Intrinsics.checkNotNullParameter(value, "value");
      String var2 = "\nSetter is called! - value: " + value + '\n';
      System.out.print(var2);
      this.bar = value;
   }

   public TestData(@NotNull String bar) {
      Intrinsics.checkNotNullParameter(bar, "bar");
      super();
      this.bar = bar;
   }

   @NotNull
   public final String component1() {
      return this.bar;
   }

   @NotNull
   public final TestData copy(@NotNull String bar) {
      Intrinsics.checkNotNullParameter(bar, "bar");
      return new TestData(bar);
   }

   // $FF: synthetic method
   public static TestData copy$default(TestData var0, String var1, int var2, Object var3) {
      if ((var2 & 1) != 0) {
         var1 = var0.bar;
      }

      return var0.copy(var1);
   }

   @NotNull
   public String toString() {
      return "TestData(bar=" + this.bar + ")";
   }

   public int hashCode() {
      String var10000 = this.bar;
      return var10000 != null ? var10000.hashCode() : 0;
   }

   public boolean equals(@Nullable Object var1) {
      if (this != var1) {
         if (var1 instanceof TestData) {
            TestData var2 = (TestData)var1;
            if (Intrinsics.areEqual(this.bar, var2.bar)) {
               return true;
            }
         }

         return false;
      } else {
         return true;
      }
   }
}
r

Richard Gomez

04/12/2022, 2:54 AM
It compiles to getBar/setBar, but in Kotlin you'd need to use a property with a setter. https://kotlinlang.org/docs/properties.html#getters-and-setters
s

Sangmin Lee

04/12/2022, 2:57 AM
Thanks for your answer Richard. I know I don’t need custom getter/setter in kotlin. What I’m trying to do is to make getter/setter in the property in primary constructor of data class. So that I can do some logic as getting/setting data.
So I come up with @JvmField and Setter/Getter in body. But it doenst’ work as I expected 😅
My colleague just teach me even in java if the field visibility is public then setting/getting value without getter/setter is not restricted.. I think I thought wrong way
d

DALDEI

07/02/2022, 7:55 AM
data class TestData( private var _bar  : String ) { 
     var bar : String  
          get() = _bar 
          set(value) {  _bar = value } 
}
or (losing the features of data class)
class TestData( _bar  : String ) { 
     var bar : String = _bar  
          get() = field  
          set(value) {  field = value } 
}