To make a class serializable we do the following:
class A implements Serializable {
transient Object a;
}
And not this:
serializable class A {
transient Object a;
}
Why, if we want to make a class serializable, do we implement a special interface. And if we want to exclude some fields we use the keyword transient?
Why aren't special keywords used in both cases? I mean were there any reasons to make the same thing in different ways? I know, there is no such keyword as serializable but why wasn't it introduced instead of the special interface Serializable?
Why isn't used some special keyword to
mark classes as serializable too?
Serializable interface looks like a
magic numbers in code and not like the
language feature.
I think you have to look at it the other way: language keywords exist mainly to support compile-time language constructs. Serialization is a runtime mechanism. Additionally, you don't want to have an extra keyword for everything, because you then can't use it as an identifier. A marker interface on the other hand is much less intrusive.
The question is thus: why do we need a language keyword to mark transient fields? And the answer is that there simply was no other way to mark specific fields at that time.
Nowadays, one would use annotations for this purpose in both cases (and for other things like the obscure strictfp keyword as well).
Serializable is a marker interface. Interfaces are a standard way (in Java and in some other languages) of indicating features of a class; an "is a" relaionship. Making Serializable an interface means we can declare methods that accept or return Serializables just like we can methods that work with other interfaces. Anything else would have required syntax changes to the language (at the time; now we have annotations, but I think an interface would still be used).
Serializable is a marker interface (like Cloneable) that is used to set a flag for standard Java runtime library code that an object can be serialised according to the designer of that class.
The transient keyword can be used to specify that an attribute does not need to be serialised, for instance because it is a derived attribute.
See also this reply to a similar question on SO and this one about designing marker interfaces.
Update
Why marker interfaces and no keywords for things like serializable, cloneable, etc? My guess would be the possibility to consistently extend the Java runtime lib with new marker interfaces combined with too many keywords if behavioural aspects made it into the language.
The fact that class attributes cannot implement Interfaces and transient can be seen as a generic property of an attribute makes sense of introducing transient as a language keyword.
So you're asking why you can't mark a class as not serializable (like a transient member)? Why wouldn't you just not mark class members of the not-to-serialize type as transient? Or use a serialization delegate for that class type when you do the serialization? It seems a little weird that you would want to tell Java to not do something at this level instead of telling it to do something.
Transient keywords are used to protect a variable or a field from being stored and we do this to protect some sensitive information we just don't want to distribute at every place and we use Serializable interface to make a class Serializable. Although we can use Externalizable interface also but we prefer to use Serializable because of some advantages.
Go though this to clearly understand Serialization and transient keyword.
http://www.codingeek.com/java/io/object-streams-serialization-deserialization-java-example-serializable-interface/
Related
What I understand is that I can implement Serializable interface to make my object serializable.
But I don't get where is writeObject method implemented when Serializable is an interface, so it doesn't contain implementation of methods, just a definition?
As you already noticed, the Serializable is a Marker Interface and does not have any methods to implement. Implementing Serializable is just a note that this one is eligible for serialization which is handled using ObjectOutputStream.
Methods you mentioned need to be implemented in a class implementing the Serializable interface and will be picked up automatically. Since there is no obligation for implementing them, they are not included in the interface.
http://docs.oracle.com/javase/8/docs/platform/serialization/spec/serial-arch.html#a4539
Tough all the answers posted so far are right, I wish to add some extra comments:
java.io.Serializable was already part of the Java 1.1 API (among the first versions of Java), and was meant as an easy way for the programmer to mark any class to have a special behaviour.
According to OOP principles, that should have been done through a regular interface, which is what you (and me, and any other programmer) would have expected. Something like this:
public interface Serializable<E>
{
public E read(DataInput input) throws IOException;
public void write(DataOutput output) throws IOException;
}
But, since there are many classes in Java which needed to be serialized, the Java Language designers wished to save troubles to programmers, by some kind of mechanism through which serialization would be performed automatically. But how?
Through an abstract class? Nope. That would have prevented any custom class to have its own hierarchy (since in Java there is only single inheritance).
Making java.lang.Object serializable? Neither so, because that would have prevented programmers to decide which class should be serializable and which should not.
On top of all, there was a hughe problem: Note that method read is supposed to create and return an object of class E from a DataInput stream. An abstract class just can not create instances of its subclasses whithout further information (the abstract class does not know which is the applied subclass).
So, they decided to pass over the OOP and offer Serialization as a special non-oop feature of the serialization classes ObjectOutputStream/ObjectInputStream (credits to EJP for this detail) in the form of a "dummy" interface recognizable by them, at the price of adding somehow some confussion to the class definitions, because an interface with no methods is nonsense (Same approach they adopted for java.lang.Cloneable).
Actually, it adds even more confussion, because custom serialization must be done by implementing private methods readObject and writeObject (as specified by ObjectOutputStream), which is a feature non describible in terms of a Java interface.
Nowadays, these kind of marking can be done through annotations. Well, think of Serializable as an interface which should have been an annotation, but still remains as an interface for those -endless- compatibility reasons.
As for the subject title: Why is it legal to declare a transient variable in a non serializable class?
What would the use be?
The transient access modifier can be seen by code other than the serialization mechanism, and is used by some object databases to mark a data field as not persistent. Aside from that, there isn't any harm in allowing this.
Because also other serialization forms that don't requirier Serializable are able to make use of it too.
How about if a subclass implements Serializable?
In any case, it is impossible for the compiler to enforce this rule, i.e. emit a compile error
based on class hierarchy (except - of course - superclass defined methods).
I have a basic question in Java, but it's a general question in OOP. Why do interfaces allow fields to be set? Doesn't that run contrary to what an interface is supposed to do?
The way I made sense of it, an interface is what in English would be an adjective. So, if my class implements the interfaces Runnable and Serializable, I'm ensuring the user that my class will satisfy the conditions to be Runnable and Seriablizable. However, that would mean interfaces are "stateless", but they are allowed to have fields in Java...
Am I missing something?
All fields in interface are public static final, i.e. they are constants.
It is generally recommended to avoid such interfaces, but sometimes you can find an interface that has no methods and is used only to contain list of constant values.
First of all, there's difference between OOP paradigm and OOP implementation in Java, so same words may mean a bit different things.
In OOP the paradigm interface is what you can do with the object (or what object can do for you). Any object can have several interfaces and thus play different roles. For example, someone may work as a programmer and be able to create programs, but at the same time he may be a husband and father and thus be able to pay the bills for his family and take care of children. Here "programmer", "husband" and "father" are interfaces, and a person is an object that implements them. Note, that interfaces do not imply presence of any specific features (fields) for implementing object, just actions that this object should be able to perform.
Java more or less follows this idea, but as any paradigm implementation has its own features. Java allows describing methods, that is actions that the implementing object should be able to perform, but not any implementation details, thus, nothing about object fields or private methods.
But what about constants (public final static fields)? Are they part of implementation or interface. It could be both. E.g. interface "programmer" can have constant WORK_HOURS set to "8". Thus Java allows you to describe constants in interfaces too.
Note, that Java only helps you to make good OOP design, but it doesn't strongly require it. In particular, not all public methods of an object should exist in interface too. For example, getter and setter methods are normally public, but in fact they are the part of implementation, not interface, and thus it's worth not to bring them into interface.
(Please also note, that most things I described here are about mainstream OOP like in Java, but there are also other kinds of OOP such as prototype-based one, in particular implemented in JavaScript).
What if that interface refers to constants? Wouldn't it be natural to declare them in the interface?
interface IdFinder {
Serializable UNSAVED = new Serializable() {};
/** #returns the given entity's persistent identity,
or {#link UNSAVED} if it hasn't been saved yet,
or null if o is a value object that hasn't a
persistent identity of its own.
*/
Serializable getId(Object o);
}
Yes, you can have constant fields in interfaces, but you are right when you say that "it seems contrary to what an interface is supposed to do", as it is not a good practice. Why would you want to have all your classes that implement an interface with the same constants? You could simply have them in the class that uses them, or if you really need to export them somehow, have them in a separate class utiliy like this:
public class Constants {
private Constants() { }
public static final int ZERO = 0;
public static final int SOME_COMPLEX_NUM = 2124132L;
...
}
You also have enums, if you need to represent a set of constant fields with some meaning. I do not see any "use case" where you would actually need constants in an interface. But could be wrong :)
In Java we implement an interface Serializable that defines no method (also called a marker interface).
But suppose I have an interface without any method just like a Serializable interface, can I make it work just like that, meaning that I would be able to use my interface instead of the Serializable?
Thanks
Only Serializable will mark an object as being compatible with Java's built-in serialization machinery.
You can create other empty interfaces, but they won't mean the same thing. Each interface is distinct, even if it defines the same set of methods.
No. If you want to be able to use Java Serialization, your objects need to implement Serializable.
If you want to use other serialization tools, (ie: Hibernate, SimpleXML, XStream), that is always a possibility, but those generally involve adding annotations, xml files, or other configurations.
If you want your object be serializable it must implement java.io.Serializable.
You could also create your own interface or class that extend from Serializable and then another class/interface extend from that one.
No. Serializable is a special interface, and you can't use a different one with the built-in serialization mechanism. You could roll your own entire system, but it'd be a big job.
If you don't implement Serializable you will not be able to use Java serialization to persist it. But you are more than welcome to implement your own persistence that is not relying on Java serialization.
Serializable is called a marker, but only because classes like ObjectOutputStream and ObjectInputStream use the reflection API to check for it. There is no special magic there; if you wanted to implement your own alternative serialization strategy, you could also create your own interface and use that as the marker you wished to respect. Although, you should consider whether it would actually be better design to use the existing Java marker (Serializable). I believe some other alternatives to the built-in Object stream do this.
If you merely wish to take complete control over how your objects are serialized into bytes, you can do so without rewriting the ObjectXXXStream classes, by using Serializable subclass Externalizable. And in fact, this is commonly done, since the automatic serialization afforded by Serializable ungracefully dies with the smallest change to the SerialVersionUID, which, unless supplied, is calculated automatically from various signatures of the class - making Serializable unsuitable for must persistent storage, since most kinds of changes (i.e. during a routine upgrade) to the underlying class will prevent reloading the serialized data.
In Effective Java, Item 17, Josh Bloch argues that putting static members into an interface (and implementing that interface) is a bad practice known as the Constant Interface Antipattern:
The constant interface pattern is a poor use of interfaces. That a class
uses some constants internally is an
implementation detail. Implementing a
constant interface causes this
implementation detail to leak into the
class's exported API. It is of no
consequence to the users of a class
that the class implements a constant
interface. In fact, it may even
confuse them. Worse, it represents a
commitment: if in a future release the
class is modified so that it no longer
needs to use the constants, it still
must implement the interface to ensure
binary compatibility. If a nonfinal
class implements a constant interface,
all of its subclasses will have their
namespaces polluted by the constants
in the interface.
There are several constant interfaces in the java platform
libraries, such as
java.io.ObjectStreamConstants. These
interfaces should be regarded as
anomalies and should not be emulated.
I'm pretty confident I understand the reasoning behind this and completely agree.
My question is: is grouping related constants (note: these are NOT suitable for an enum, consider the math example of the related constants pi and e) in an interface versus a non-instantiable class a good idea, provided you only access the values via static references and static imports, keep the interace hidden from your API w/ a default access modifier, and never actually implement the interface?
Why or why not? Are there any advantages are there to grouping them in a class other than being able to use a private constructor to ensure the constant grouping type is never instantiated?
Let's put it the other way. There is no advantage of using interfaces for constants. As you know, interfaces are for defining contracts, not for constants. I don't see the problem of changing the interface keyword to class keyword and using public static final fields for example. Using interfaces for keeping constants is never a good idea. I think people use this anti-pattern because they don't know about static imports(it was introduced in Java 5.0) or they are too lazy to dispatch their constants in the appropriate classes. Instead they just create one interface and let every class implement it.
Edit: By the way the question sounds me like - Is it a good idea to watch television, looking at the neighbourhood's TV using a telescope, provided the seeing is good. The answer is simple - no, the telescope is invented for other things. Ah, and I know this example is dumb:)