<p>In Java, static and transient fields are not serialized. However, I found out that initialization of static fields causes the generated serialVersionUID to be changed. For example, <code>static int MYINT = 3;</code> causes the serialVersionUID to change. In this example, it makes sense because different versions of the class would get different initial values. Why does any initialization change the serialVersionUID? For example, <code>static String MYSTRING = System.getProperty("foo");</code> also causes the serialVersionUID to change.</p>

<p>To be specific, my question is why does initialization with a method cause the serialVersionUID to change. The problem I hit is that I added a new static field that was initialized with a system property value (getProperty). That change caused a serialization exception on a remote call.</p>

[{'answer_id': 41515, 'author': 'Alfred B. Thordarson', 'author_id': 3379, 'author_profile': 'https://Stackoverflow.com/users/3379', 'pm_score': 0, 'selected': False, 'text': '<p>If I read the spec correctly the automatic <code>serialVersionUID</code> shouldn\'t change if you change the value of a static of transient field. Take a look at <a href="http://java.sun.com/javase/6/docs/platform/serialization/spec/version.html#6678" rel="nofollow noreferrer">Chapter 5.6</a> of the Spec.</p>\n\n<p><strong>However</strong>, if you think about this a bit - you start by serializing an object that has <code>static int MYINT = 3</code>, when you then deserialize the class you expect to get the same object back, that is, with <code>MYINT = 3</code>. So, if you change the static initialization you would expect the <code>serialVersionUID</code> to change because you can\'t get the same object back again.</p>\n\n<p><strong>Anyways</strong>, keep this in all your serializable classes and you can control the <code>serialVersionUID</code>:</p>\n\n<pre><code>private static final long serialVersionUID = 7526472295622776147L;\n</code></pre>\n'}, {'answer_id': 41527, 'author': 'David G', 'author_id': 3150, 'author_profile': 'https://Stackoverflow.com/users/3150', 'pm_score': 0, 'selected': False, 'text': '<p>I updated the question to be more clear. I understand why initialization with a literal changes the <code>serialVersionUID</code> but not why dynamic initialization changes it. If you initialize with a method, the value, of course, may always be different.  </p>\n\n<p>Setting the <code>serialVersionUID</code> explicitly is fine in a subsequent version of the class only if you are sure that it is a safe change. </p>\n'}, {'answer_id': 42674, 'author': 'Damien B', 'author_id': 3069, 'author_profile': 'https://Stackoverflow.com/users/3069', 'pm_score': 4, 'selected': True, 'text': '<p>You can find some information about that in the <a href="http://bugs.sun.com/view_bug.do?bug_id=4365406" rel="nofollow noreferrer">bug 4365406</a> and in the <a href="http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/class.html#4100" rel="nofollow noreferrer">algorithm for computing <strong>serialVersionUID</strong></a>. Basically, when changing the initialization of your <code>static</code> member with <code>System.getProperty()</code>, the compiler introduces a new <code>static</code> property in your class referencing the <code>System</code> class (I assume that the <code>System</code> class was previously unreferenced in your class), and since this property introduced by the compiler is not private, it takes part in the <code>serialVersionUID</code> computation.</p>\n\n<p><strong>Morality</strong>: always use explicit <code>serialVersionUID</code>, you\'ll save some CPU cycles and some headaches :)</p>\n'}, {'answer_id': 46043, 'author': 'Tom Hawtin - tackline', 'author_id': 4725, 'author_profile': 'https://Stackoverflow.com/users/4725', 'pm_score': 2, 'selected': False, 'text': '<p>Automatic serialVersionUID is calculated based on members of a class. These can be shown for a class file using the javap tool in the Sun JDK.</p>\n\n<p>In the case mentioned in the question, the member that is added/removed is the static initialiser. This appears as ()V in class files. The contents of the method can be disassembled using javap -c. You should be able to make out the System.getProperty("foo") call and assignment to MYSTRING. However an assignment with a string literal (or any compile-time constant as defined by the Java Language Specification) is supported directly by the class file, so removing the need for a static initialiser.</p>\n\n<p>A common case for code targeting J2SE 1.4 (use -source 1.4 -target 1.4) or earlier is static fields to old Class instances which appear as class literals in source code (MyClass.class). The Class instance is looked up on demand with Class.forName, and the stored in a static field. It is this static field that disrupts the serialVersionUID. From J2SE 5.0, a variant of the ldc opcode gives direct support for class literals, removing the need for the synthetic field. Again, all this can be shown with javap -c.</p>\n'}]
['https://Stackoverflow.com/questions/41499', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3150/']