The Java Annotation interface does not extend Serializable. However, Java annotation values are serializable (implemented using java.lang.reflect.Proxy, with a serializable invocation handler).
Is this guaranteed anywhere? My search-foo is failing to find a reference. Or if I need to serialize annotation instances safely, do I need to create my own serialization proxies?
Annotation objects returned by methods of java.lang.reflect.AnnotatedElement are Serializable. This is what API says: This interface allows annotations to be read reflectively. All annotations returned by methods in this interface are immutable and serializable.
All classes capable of returning annotation objects (Class, Constructor, Field, Method, Package, Parameter) implement AnnotatedElement and are obliged to create / return Serializable objects by the above contract.
Annotations are part of the class definition, and thus would never be written to a serialization stream (at least not with standard java serialization) when serializing an instance of a class which has annotations.
UPDATE:
I guess i missed the point of the original question which was referring to specifically serializing an instance of an actual Annotation.
Related
I have an interface A, and implementation of this interface AImpl
Interface has 1 method which is implemented in AImpl.
Implementation AImpl has few members and no serialVersionUID.
Question what will happen If new default method will be added to interface A, without overriding it in AImpl ? Have I did break here? Will I have same result of serialization/deserialization ?
Not only are methods not serialized, but interfaces are not serialized either.
The purpose of serialization is to write the data associated with an object, not it's behaviour (unless this is explicitly encoded as data as well, e.g. GregorianCalendar's TimeZone)
There is no way to see in a serialized object what interfaces or methods the class has so changing them has no effect.
(You might infer about the methods used for serialization only)
Java serialization does encode the super-class hierarchy of a class so you can't change that easily.
However, most serialization libraries don't do this and you can't see this information nor does it matter if you change them. The downside is that many serialization libraries don't support having the same field name multiple times in your class hierarchy but Java serialization does.
This question already has answers here:
Although the Serializable interface in Java has no methods, no fields, it can achieve its function. How?
(6 answers)
Closed 7 years ago.
I know what is serialization and why it is used, but my question:
Why is serialization a marker interface?
What is the potential benefit of not having writeObject, readObject in Serializable interface because when we do serialization we finally override these 2 methods?
How does readResolve ensure that the object created during deserialization is not the new object. I know the below and it is returning the same object during deserialization but who will call this readResolve method internally?
private Object readResolve() throws java.io.ObjectStreamException {
return INSTANCE;
}
Because there needs to be some explicit way of declaring a class to be serializable. The framework can't just assume all classes to be serializable, as there are many kinds of objects that will stop working if their fields are written to disk and are later reloaded from there (e.g. FileInputStream, which relies on an open operating system file handle which might no longer exist when the object is deserialized). The modern way of having such a declaration would be an annotation, but those didn't exist in Java at the time serialization was added.
You won't necessarily need to override them - if the default behavior of the serializer is good enough; you don't need to do anything but implement Serializable.
The serialization framework calls it when an object has been completely deserialized. At this time, the object is allowed to inspect its own contents, and if it decides that it should instead be represented by another instance, it can return that instance instead (if not, it returns this). Whatever comes out of this method is returned to the code that requested the deserialization. If a preexisting object was returned, the new object created by the deserializer will not be seen by anyone and will eventually be garbage collected.
Marker Interfaces are used to tell JVM to perform specific tasks. they don't have any method. Serializable is also a marker interface.
Serialization is the process of flattening the objects. when you implement serializable interface in a class, it tells JVM to serialize its object i.e. it has to be converted into stream.
We don't need it if we're implementing Serializable. So why this difference? How does it relate to the actual mechanism of Serialization?
A thorough explanation (although the grammar of the article might be improved) can be found on http://www.jusfortechies.com/java/core-java/externalization.php . The short answer, for future reference in case the linked page goes away:
Externalizable is an interface extending Serializable. Contrary to Serializable, though, objects are not restored by just reading the serialized bytestream, but the public constructor is called and only once the object is thus created, its state is restored. This makes restoring more efficient.
Edit: See also What is the difference between Serializable and Externalizable in Java? .
This is primarily used for caching purposes. In order to deserialize across streams, you will need to spell out how you want your object to be deserialized, hence the two methods provided by the contract in Externalizable interface: writeExternal and readExternal. Note that Externalizable extends Serializable, so you don't necessarily need to implement Serializable interface (although it's a marker interface and there are no methods to be actually implemented).
For a sample implementation, have a look at MimeType.
A public no-arg constructor is needed while using Externalizable interface.
Because in case of Serializable
readObject reads the required information from the ObjectInputStream
Serialization uses reflection mechanism to get the necessary fields and their corresponding values.
Serializable serializes all the data members (except static and transient).
But in case of Externalizable
No reflection mechanism used.
User doesn't serializes all data members.That's why to fetch values of the members which are not externalized public no arg constructor is required.
Suppose I had an interface with some annotation(s), for example:
#SpecialClass
public interface IFoo { /* ... */ }
And suppose I make a class that implements the interface:
public class Foo implements IFoo { /* ... */ }
Is it possible for class Foo to somehow "inherit" or automatically copy all or some of the annotations from IFoo and its members (e.g. automagically annotate Foo as #SpecialClass, etc.)?
This would be convenient for implementing web service classes (e.g. those generated by the JAX-WS "wsimport" tool) by just implementing their annotated interfaces without explicitly having to copy the interface annotations to the implementing class (e.g. javax.jws.WebService, javax.xml.ws.RequestWrapper, etc).
EDIT: I'm leaving this answer here for general information and future readers, but Andreas pointed out an important bit of the Javadoc which I'd missed:
Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.
In other words, it wouldn't help in this situation. Also it's only useful if you have control over the annotation itself, of course.
I suspect the real answer is that you simply have to apply the annotation everywhere. If you're worried about forgetting one, you might want to write a unit test which finds all your classes (easier said than done, I realise) and checks that the annotation is present for all classes implementing the given interface.
Have you tried applying the Inherited annotation to the SpecialClass annotation itself?
Indicates that an annotation type is automatically inherited. If an Inherited meta-annotation is present on an annotation type declaration, and the user queries the annotation type on a class declaration, and the class declaration has no annotation for this type, then the class's superclass will automatically be queried for the annotation type. This process will be repeated until an annotation for this type is found, or the top of the class hierarchy (Object) is reached. If no superclass has an annotation for this type, then the query will indicate that the class in question has no such annotation.
That certainly sounds like exactly what you want.
How can I serialize an object that does not implement Serializable? I cannot mark it Serializable because the class is from a 3rd party library.
You can't serialise a class that doesn't implement Serializable, but you can wrap it in a class that does. To do this, you should implement readObject and writeObject on your wrapper class so you can serialise its objects in a custom way.
First, make your non-serialisable field transient.
In writeObject, first call defaultWriteObject on the stream to store all the non-transient fields, then call other methods to serialise the individual properties of your non-serialisable object.
In readObject, first call defaultReadObject on the stream to read back all the non-transient fields, then call other methods (corresponding to the ones you added to writeObject) to deserialise your non-serialisable object.
I hope this makes sense. :-)
Wrap the non-serializable class in a class of your own that implements Serializable. In your class's writeObject method, do whatever's necessary to serialize sufficient information on the non-serializable object so that your class's readObject method can reconstruct it.
Alternatively, contact the developer of the non-serializable class and tell him to fix it. :-)
You can use Kryo. It works on non serialized classes but classes needs registered aforehand.
If your class already implements the Serializable interface (required for serializing), all you must do is to declare the field you don't want to serialize with transient:
public transient String description;
If the class is not final, you can make your own class that extends it and implements Serializable. There are lots of other ways to serialize besides Java's built-in mechanism though.