Use the serialVersionUID or suppress warnings?

33,700

Solution 1

I don't know Java best practices, but it occurs to me that if you are claiming that serialization will never happen, you could add a writeObject method which throws. Then suppress the warning, safe in the knowledge that it cannot possibly apply to you.

Otherwise someone might in future serialize your object through the parent class, and end up with a default serialized form where:

  • the form isn't compatible between different versions of your code.
  • you've suppressed the warning that this is the case.

Adding an ID sounds like a bodge, since what you really want to do is not serialize. Expecting callers not to serialize your object means that you expect them to "know" when their HttpServlet is of your class. That breach of polymorphism is on your head for having a Serializable object which must not be serialized, and the least you can do is make sure unwary callers know about it.

Solution 2

If you do not plan to serialize instances, add a SuppressWarning.

A generated serial ID can be a bit dangerous. It suggests that you intentionally gave it a serial number and that it is save to serialize and deserialize. It's easy to forget to update the serial number in a newer version of your application where your class is changed. Deserialization will fail if the class fields have been changed. Having a SuppressWarning at least tells the reader of your code that you did not intend to serialize this class.

Solution 3

I refuse to be terrorized by Eclipse into adding clutter to my code!

I just configure Eclipse to not generate warnings on missing serialVersionUID.

Solution 4

Thanks @ Steve Jessop for his answer on this. It was 5 lines of code... hardly a hassle.

I added @SuppressWarnings("serial") just above the class in question.

I also added this method:

private void writeObject(ObjectOutputStream oos) throws IOException {
   throw new IOException("This class is NOT serializable.");
}

Hopefully that's what Steve meant :)

Solution 5

Even if you know this object will be serialized there is no need to generate serialVersionUID because java will automatically generate it for you and will automatically keep track of changes so your serialization will always work just fine. You should generate it only if you know what you are doing (backward serialization compatibility, manual change tracking etc.)

So I would say suppressing the warning is the best and safest solution in most cases.

Share:
33,700
Okami
Author by

Okami

Updated on July 05, 2022

Comments

  • Okami
    Okami almost 2 years

    I want to create a class that, for example, extends HttpServlet? My compiler warns me that my class should have a serialVersionUID. If I know that this object will never be serialized, should I define it or add an annotation to suppress those warnings?

    What would you do and why?

  • skaffman
    skaffman over 15 years
    I disagree. The ID in this case is useless clutter. This warning should, in my opinion, be suppressed.
  • Okami
    Okami over 15 years
    I think it's a lot of overhead but in a professional environment this seems quite necessary.
  • cynicalman
    cynicalman over 15 years
    Just want to second the motions that you make sure you prohibit serialization (ie with an exception) if you aren't going to support it.
  • McDowell
    McDowell over 15 years
    Warnings are a prompt asking you to make an informed decision, not instructions that are to be blindly followed.
  • brady
    brady over 15 years
    A serial version UID member is not added to classes at compile-time. If it is missing, it is computed from the member signatures of the class at runtime. It only changes when the signatures change, not necessarily with every compilation.
  • Scott Stanchfield
    Scott Stanchfield over 15 years
    if you want to serialize something, you should always provide an explicit version value (1, 2, 3, ...). This allows you to tell Java serialization when compatibility is broken. For example, if all you're doing is adding fields, it can still read old .ser files with the same version.
  • The Student
    The Student about 14 years
    I think that add @suppressWarning and throw exception when you do not support serialization is the best approach in a professional evironment. Your IDE to remembers you of serialization may be important in much cases.
  • The Student
    The Student about 14 years
    I'm not so sure about that.. If you add the SVUID it´s good to see what are you letting serialize. It can cause security problems if a client can get a password field by serializing your whole program.
  • james raygan
    james raygan about 14 years
    Generating SVUID in Serializable classes has nothing to do with serializable fields. Of course, you should pay attention to which fields are serialized.
  • Justin
    Justin about 14 years
    true that, whats worse, you cannot add suppress warning to a package!
  • Justin
    Justin about 14 years
    If you generate a SVUID of 1 for example, then change the layout of your class that now means you must maintain SVUID (and update to 2). Most people won't maintain this. This is unnecessary if you don't intend the class to be serialized.
  • Justin
    Justin about 14 years
    I would not go through the trouble of preventing serialization from ever happening. Just don't declare a SVUID, which means that each compile a unique one will be generated; making serialization unreliable but not breaking applications which depend on it, inadvertently.
  • james raygan
    james raygan about 14 years
    "SVUID to every class implementing serializable" If class is serializable there is always someone in the world who wants to serialize it. In general, my target was not to solve people's laziness.
  • Laurence Gonsalves
    Laurence Gonsalves over 13 years
    @Scott you don't always need to provide an explicit version value even when you are serializing. It depends on the serialization scope and the consequences of failing to deserialize. If you will only ever deserialize objects that were serialized by the same version of the code (like saving instance state on Android) then the auto-generated ID is fine. Also, if your serialized objects are merely a cache that you can reconstruct if serialization fails then that's also ok. A manual ID adds a lot of development overhead as you need to properly need to deal with version skew in deserialization.
  • dominicbri7
    dominicbri7 almost 13 years
    I agree with Tom, most of the time it is annoying and unnecessary, but it SOMETIMES is useful and important. If you still use that approach for your project, I suggest you configure your Project to do so and not Eclipse itself (which will apply it to each and every project). Using @suppressWarning will get rid of the annoying occurences, but the "necessary" ones will not be muted.
  • orbfish
    orbfish over 12 years
    AFAIK default UID is generated from the object graph, not by compile. Someone else says the same thing below and I'm sure it says that in Effective Java.
  • engfer
    engfer about 12 years
    UnsupportedOperationException might be more acceptable, but the private methods might be unnecessary
  • Praveen Prajapati
    Praveen Prajapati almost 12 years
    @McDowell The Serialization JavaDoc says it's strongly recommended. I mean, sure, you can just say the Sun/Oracle guys are nuts and you have a better idea of what's going on in Java than them. But the comment on the original question ("servlets might be serialized") indicates that sometimes (only sometimes) developers assume to know what happens but actually don't. See "select() isn't broken".
  • Stefan
    Stefan over 11 years
    @Justin Unreliable is not a word i would want mentioned in the same sentence as my app.
  • marcus
    marcus over 11 years
    I'm not sure it will save me from trouble. If I change the class and never change the generated ID, I am explicitly telling the compiler/JVM that old classes are still compatible. If I just let the runtime calculate and ID, it at least has some chance to detect incompatibilities that a human couldn't see.
  • Alex Cohn
    Alex Cohn about 9 years
    This is a nice try; unfortunately, it will not warn at compile time :(
  • Stijn de Witt
    Stijn de Witt about 7 years
    @marcus: You are absolutely right. If you set an ID (whether just 1L or some generated one) hardcoded in the class, you are basically taking the burden of updating that ID each time there are compatibility changes if you want things to work as they should. They are basically like a library version, but on the class level. Specifying an ID and then never changing it is much more harmful then just not specifying it. (let alone throwing an exception in writeObject which will turn out to be a maintenance nightmare I am predicting).
  • oligofren
    oligofren about 3 years
    That it throws when the version number changes is a good thing. That is precisely why you should not implement it when you have no intention of serializing things, as it will alert you that this is in fact being done, and you need to change your classes to support it.