What Does It Mean: the Serializable Class Does Not Declare a Static Final Serialversionuid Field

What does it mean: The serializable class does not declare a static final serialVersionUID field?

From the javadoc:

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named "serialVersionUID" that must be static, final, and of type long:

You can configure your IDE to:

  • ignore this, instead of giving a warning.
  • autogenerate an id

As per your additional question "Can it be that the discussed warning message is a reason why my GUI application freeze?":

No, it can't be. It can cause a problem only if you are serializing objects and deserializing them in a different place (or time) where (when) the class has changed, and it will not result in freezing, but in InvalidClassException.

What is a serialVersionUID and why should I use it?

The docs for java.io.Serializable are probably about as good an explanation as you'll get:

The serialization runtime associates with each serializable class a version number, called a serialVersionUID, which is used during deserialization to verify that the sender and receiver of a serialized object have loaded classes for that object that are compatible with respect to serialization. If the receiver has loaded a class for the object that has a different serialVersionUID than that of the corresponding sender's class, then deserialization will result in an
InvalidClassException. A serializable class can declare its own serialVersionUID explicitly by declaring a field named serialVersionUID that must be static, final, and of type long:

ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;

If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class — serialVersionUID fields are not useful as inherited members.

What does the declare a static final serialVersionUID warning mean and how to fix?

This is explained fairly well here:

The serialVersionUID is a universal version identifier for a Serializable class. Deserialization uses this number to ensure that a loaded class corresponds exactly to a serialized object. If no match is found, then an InvalidClassException is thrown.

You fix the error by adding

private static final long serialVersionUID = 7526472295622776147L;  // unique id

to the class.

Further reading:

  • java.io.Serializable
  • Why should I bother about serialVersionUID? (stackoverflow)

A side note: If you're using Eclipse and if you (and no one else) ever plan to serialize your classes, you can also suppress the error by going to

     Window → Preferences → Java → Compiler → Errors/Warnings

and select "Ignore" on "Serializable Class without serialVersionUID".

The serializable class Employee does not declare a static final serialVersionUID field of type long

How does IDE assign default value. Is it hard coded in the IDE?

yes default is hard coded value, which is 1L

When it says generate id what parameters are used to generate new id?

generally method fields and method signatures should used to determine it, since you are asking specifically about eclipse, not sure about it, there is a serialver utillity which simply gives you serialVersionUID for your class

$serialver A
serialver A: static final long serialVersionUID = -609421954100196333L;

Not sure what the 3rd option is. Says something about suppress annotation. Does that mean no id is assigned at all. In that case what is used in serialization?

it says, instruct java compiler to not complain about this particular warning for this case by adding @SuppressWarning annotation


Also See

  • Eclipse auto-generation of serialVersionUID with each change
  • About generated serialVersionUID in Eclipse

Understanding this warning: The serializable class does not declare a static final serialVersionUID

The syntax you're using is called double-brace initialization - which is actually an "instance initialization block that is part of an anonymous inner class" (certainly not a hack). So, when using this notation, you are actually defining a new class(!).

The "problem" in your case is that HashMap implements Serializable. This interface doesn't have any methods and serves only to identify the semantics of being serializable. In other words, it's a marker interface and you concretely don't have to implement anything. But, during deserialization, Java uses a version number called a serialVersionUID to verify that the serialized version is compatible with the target. If you don't provide this serialVersionUID, it will be calculated. And, as documented in the javadoc of Serializable, the calculated value is extremely sensitive and it is thus recommended be explicitly declare it to avoid any deserialization problems. And this is what Eclipse is "complaining" about (note that this is just a warning).

So, to avoid this warning, you could add a serialVersionUID to your annonymous inner class:

someMethodThatTakesAHashMap(new HashMap<String, String>() {
private static final long serialVersionUID = -1113582265865921787L;

{
put("a", "value-a");
put("c", "value-c");
}
});

But you loose the conciseness of the syntax (and you may not even need it).

Another option would thus be to ignore the warning by adding a @SuppressWarnings("serial") to the method where you are calling someMethodThatTakesAHashMap(Map). This seems more appropriate in your case.

That all being said, while this syntax is concise, it has some drawbacks. First, if you hold a reference on the object initialized using a double-brace initialization, you implicitly hold a reference to the outer object which won't be eligible for garbage collection. So be careful. Second (this sounds like micro optimization though), double-brace initialization has a very a little bit of overhead. Third, this technique actually uses anonymous inner classes as we saw and thus eats a bit of permgen space (but I doubt that this is really a problem unless you really abuse them). Finally - and this is maybe the most important point - I am not sure it makes the code more readable (it's not a well known syntax).

So, while I like to use it in tests (for the conciseness), I tend to avoid using it in "regular" code.

how to remove the warning The serializable class ClASSNAME does not declare a static final serialVersionUID field of type long

Add an annotation @SuppressWarnings("serial") on your class, to ignore that warning

The serializable class X does not declare a static final serialVersionUID field of type long

Although it doesn't say so in the javadoc you linked, play.db.ebean.Model implements com.avaje.ebean.bean.EntityBean (see https://github.com/playframework/play-ebean/blob/master/play-ebean/src/main/java/play/db/ebean/Model.java), which in turn extends java.io.Serializable (see http://www.avaje.org/static/javadoc/pub/com/avaje/ebean/bean/EntityBean.html). So, Eclipse is correct.



Related Topics



Leave a reply



Submit