Search code examples
javakotlinencapsulation

Access field in kotlin class and ignore getter


Consider this class in java (data is not private or public):

public class Poo {
    String data = null;

    public String getData() {
        if (data == null)
            return "";
        else
            return data.substring(0, 4);
    }

    public void setData(String data) {
        this.data = data;
    }

    public String getDataPart2() {
        if (data == null)
            return "";
        return data.substring(4);
    }
}

I convert this class to kotlin

class Poo1 {
    var data: String? = null
        get() = field?.substring(4) ?: ""

    val dataPart2: String
        get() = data?.substring(4) ?: ""
}

the decompiled code is like this:


   @NotNull
   public final String getDataPart2() {
      String var10000 = this.getData();
      if (var10000 != null) {
         String var1 = var10000;
         byte var2 = 4;
         boolean var3 = false;
         if (var1 == null) {
            throw new TypeCastException("null cannot be cast to non-null type java.lang.String");
         }

         var10000 = var1.substring(var2);
         Intrinsics.checkExpressionValueIsNotNull(var10000, "(this as java.lang.String).substring(startIndex)");
         if (var10000 != null) {
            return var10000;
         }
      }

      var10000 = "";
      return var10000;
   }

in kotlin class dataPart2 calls data getter(check line 2 in decompiled code), but I need to access data actual value not the getter, is it possible in kotlin to access field and not call getter? I don't want to change getter or method names.


Solution

  • No, it's not possible. I would strongly suggest to change the design of the class: the setter sets the complete data, and the getter only gets the first part of it, making it extremely surprising, and thus a source of bugs.

    But anyway, if you want to keep what you have in Kotlin, you can use this:

    class Poo {
        private var completeData: String? = null
    
        var data: String
            get() = completeData?.substring(0, 4) ?: ""
            set(value) { completeData = value }
    
        val dataPart2: String
            get() = completeData?.substring(4) ?: ""
    }