How to generate serialVersionUID for kotlin except

2019-04-07 20:51发布

问题:

As kotlin doesn't have static fields, should I define serialVersionUID in companion object?

回答1:

Yes, you can declare it in the companion object. The doc says:

Also, public properties defined in objects and companion objects, as well as top-level properties annotated with const, are turned into static fields in Java

But that seems to be the case with private properties too:

class MyException: Exception() {
    companion object {
        private val serialVersionUid: Long = 1
    }
}

javap -c -p com.ninja_squad.kotlindiscovery.MyException.class

Compiled from "MyException.kt"
public final class com.ninja_squad.kotlindiscovery.MyException extends java.lang.Exception {
  private static final long serialVersionUid;

  public static final com.ninja_squad.kotlindiscovery.MyException$Companion Companion;

  static {};
    Code:
       0: getstatic     #38                 // Field com/ninja_squad/kotlindiscovery/MyException$Companion.INSTANCE:Lcom/ninja_squad/kotlindiscovery/MyException$Companion;
       3: putstatic     #40                 // Field Companion:Lcom/ninja_squad/kotlindiscovery/MyException$Companion;
       6: lconst_1      
       7: putstatic     #21                 // Field serialVersionUid:J
      10: return        

  public com.ninja_squad.kotlindiscovery.MyException();
    Code:
       0: aload_0       
       1: invokespecial #15                 // Method java/lang/Exception."<init>":()V
       4: return        

  public static final long access$getSerialVersionUid$cp();
    Code:
       0: getstatic     #21                 // Field serialVersionUid:J
       3: lreturn       
}


回答2:

To create the serialVersionUID for a class in Kotlin you have a few options all involving adding a member to the companion object of the class.

The most concise bytecode comes from a private const val which will become a private static variable on the containing class, in this case MySpecialCase:

class MySpecialCase : Serializable {
    companion object {
        private const val serialVersionUID: Long = 123
    }
}

You can also use these forms, each with a side effect of having getter/setter methods which are not necessary for serialization...

class MySpecialCase : Serializable {
    companion object {
        private val serialVersionUID: Long = 123
    }
}

This creates the static field but also creates a getter as well getSerialVersionUID on the companion object which is unnecessary.

class MySpecialCase : Serializable {
    companion object {
        @JvmStatic private val serialVersionUID: Long = 123
    }
}  

This creates the static field but also creates a static getter as well getSerialVersionUID on the containing class MySpecialCase which is unnecessary.

But all work as a method of adding the serialVersionUID to a Serializable class.