You can have final and transient together for an instance variable (transient NEVER makes sense with a static variable, because static variable values are never saved as part of an object's state).
You need to be allowed to mark a variable as transient for whatever normal reasons you have (it's not serializable, or its really big, or its a security risk to let this part of the object be saved into a file, etc.).
BUT... its dangerous if the variable is final.
Remember that final means that once assigned the value can't be changed.
And you get TWO chances (as of
Java 2) to assign that initial (and forever) value:
1) Explicit initialization (in other words, at the moment of declaration -- final int x = 17;
2) In the constructor. If you haven't assigned the final variable an explicit value, then the compiler will make sure that you have given it one in the constructor. This is called a BLANK FINAL (a final that is declared but not explicitly initialized.)
With transient, the problem is that transient variables are restored at de-serialization with their default values, because explicit initialization doesn't run and neither does the constructor when an object is de-serialized. So an int variable explicitly (or in the constructor) initialized to, say, 5 will come back as 0.
BUT... with a transient variable that is also FINAL, Java does a little trick and runs the explicit initialization again -- just for the final variable, not the non-final transient variables -- so that the final variable is assigned its original value again.
BUT... that only works if the final transient variable is NOT a BLANK FINAL.
So the bottom-line: you can use final and transient together, and may need to. But if you DO use a final variable, you better give it an explicit value rather than wait for the constructor, or you can have a scenario where the object gets de-serialized and the final variable now has a different value (the default values) and you can't reassign it!!
(and even the normal way to recover from this -- using a private readObject method -- won't work because you can never, ever reassign a value to a private variable --- even while its in the process of being deserialized. Only Java itself can re-run your explicit initialization for that final transient variable).
cheers,
Kathy