Is there a way where I can prevent the parent class to be serialized?
When we do a serialization of the subclass all the way up till the parent class the serialization is performed.
Can I restrict the serialization of the parent classes and serialize the only sub class I am working on?
It is possible. Just declare your class as implements Externalizable and write exactly what you need in the writeExternal() method, taking care not to serialize anything from the superclass, and read exactly that back in the readExternal() method.
Or, just implement Serializable and provide your own readObject()/writeObject() methods, again taking care not to serialize anything from the superclass, and in this case also not calling defaultWriteObject() or defaultReadObject().
In both cases the actual serialization of the current class's data is entirely up to you.
Whilst it is technically possible to fine tune each level of inheritance on its own - even to the extent of excluding super class fields - you might want to step back here.
Basically there are two cases:
The super class does not have any fields / state. Then you have nothing to exclude anyway.
The super class has state, represented by fields of that class.
So how do you think to meaningfully address the second part? You see when you allow deserialisation without the data for the super class fields - that means that you might have to do a lot of additional testing. To make sure that super class methods don't throw exceptions - because all of a sudden fields are null instead of being initialized.
In other words: it is possible that "leaving out" all these values - you are creating objects which behave completely different. Are you prepared for handling all the effects of that?
Meanung: skipping super class fields requires you to interfere with serialization code. It might require a lot of additional testing effort. And what do you gain? A few bytes less of data transfer at runtime.
Beyond that: what is the purpose of an inheretance hierarchy that has 4 levels - but where the super class state is irrelevant?
So my non-answer: carefully consider if your idea is really the best OO design to solve the underlying requirements.
Related
I was wondering whether Class instances are immutable. The declared methods names do not suggest that the instance state is changed when they are invoked, but I found no explicit guarantee on the javadoc.
Scenario: I need to store unique class names in a Set. Ideally, I would like to populate the set with Class instances to avoid unnecessary calls to Class.forName() when I need to access the classe via reflection. However, it preferable to use immutable objects as keys of sets. Hence I was wondering if I could use Class instances right away.
First, The generics part Class<?> really doesn't matter here. Sure, no raw types, so Class<?> is better than Class, but for your question, the wildcard doesn't matter.
So in essence, you are asking whether Class objects are immutable. And for all practical purposes, they are.
Class objects come into existence when a class loader loads a class, and they stay put unless the whole class loader is unloaded, and everything it loaded with it.
Which can't happen when such class objects are still used in a map somewhere.
On the other hand: Class.forName() shouldn't be too expensive for classes already loaded. And when things such as serialization come into play, people suggest to go with String instead of Class objects for example (see here).
One has to distinguish between the immutable identity of a class object, and the actual "code" belonging to the class. That code can be changed at runtime (by instrumentation, think hot swap of code). But the class name, and its each code, and equals() equality should not be affected by that. Because the "identity" stays the same.
Final note: as the interesting comments below lay out, there are certain ways to alter Class objects to a certain degree. But all of these activities are definitely "out of the norm". Therefore: theoretically, you might prefer Strings over Class objects, but practically, in "normal" applications, using Class should work fine, too.
As I don’t really agree with other answer I decided to write this one,
Classes are not immutable, but they are unique - only one instance of Class object can exist for one class.
BUT class it not defined by its name, as classes might be from different class loaders, and different class loaders might have classes with same names - but that will be different classes, you would get ClassCastException if you would pass some object between code handled by 2 different class loaders if that object type would exist in both of them (as separate one, not inherited).
Class instances can be still safely used in Set, as they use default implementation of hashset/equals so only same instances of Class will be considered equals.
But to decide if you should use String or Class you need to know how exactly your app is supposed to work, as like I said, multiple classes with same name can exist between different class loaders.
And by just storing class name you can’t be sure that Class.forName will return same instance as expected it might even load some other class with same name from current class loader instead of using expected one.
I have the main abstract class that is a base for bunch of classes. Some of them does not need all the fields and methods from the main abstract class, so I have created second abstract class and splitted main abstract class into two parts. The main abstract class contains, for example, a, x fields and their getters/setters, the second abstract class inherits from the main and contains additional b, c fields and their getter/setters. There are simple classes that are inheriting from the main class,and more complicated are inheriting from the second class. I want to create objects of each class as instances of the main class. Is it right way to do that? I have to type check and cast when I want to use methods from the second abstract class. It makes my code complicated. How can I solve this problem?
MainAbstractClass ---> SecondAbstractClass ---> MyComplicatedClasses
|
|
V
MySimpleClasses
One of the OO principles is Favor composition over inheritance.
This means that common behavior is not provided through base classes but via Component classes which are passed in via dependency injection (preferably as constructor parameters.
The answer depends on your actual needs.
You can instead choose to store the extended abstract class specific fields in a class that does not implement your base class and make it a member of more complicated classes.
You can choose to keep everything in a single base class and nothing forces you to use all the fields of an interface in every class that implemented your interface.
You can also keep using your approach but since you store the classes as an instance of the base class, it will be hard to read.
I believe that if you think code does not look very good, it is probably not good. However, there is usually no single answer to this kind of design questions and the best solution is relative to your preferences.
I think this need of type cast is a smell of fragile design. Here when we assume MyComplicatedClass ISA KIND OF MainAbstractClass as shown by TJ Crowder then object must behave as MainAbstractClass (meaning it can honor only API of MainAbstractClass). If it expects special treatment as MyComplicatedClass its false commitment and will need Casting. Such casting (by identifying type) goes against OO principles and kills polymorphism. Later this will end up in Ladder of InstanceOf and type casts as in the scenarios rightly pointed out by T.J. Crowder.
I would suggest readdress the design. e.g. though our all user defined type instances ARE KIND OF Object, but we use Object API only for methods defined in Object class. We do not use Object o = new MyClass(). There are occasions in frameworks or like Object.equals() method where type cast is needed as API is defined before even concrete extension is written. But it is not a good idea for such simple complete (without open hooks for extensions) Hierarchies.
We all know state of an Object is value of it's attributes (instance variables), but if class doesn't has any attribute (no inherited attributes), what would be the state of an Object of such class.
There is a word for such objects - stateless.
There is no such thing as a Java class without a parent class. The default parent would be used, e.g. java.lang.Object.
At a minimum every instance of a class has two attributes: a reference address and a Class type. Note, not every class can be instantiated. There is also some space used in the ClassLoader and any String(s) may (or may not) be interned. This actual implementation might vary slightly on the specific version of the JDK and run-time platform, and additional optimizations can be added by the JIT. However, as a Java developer you are not responsible for this memory management and I would be wary of premature optimization.
first thing
any class we write in java will extend Object class by default if there is no extends written by the developer.
so each and every class will definitely have a parent with no doubt atleast Object class.
second
if you dont put any attributes in your class , obviously it will get all the instance variables except private gets inherited to your class.
so it will have atleast object state but it will not serve any purpose
An object with no data members and links to other objects is a stateless object and in this form can hardly be of any use.
This kind of classes can nevertheless be usefull, because of its methods. It can be...
a base for a further inheritance. It declares/defines some methods, that could be inherited by derived classes. This class will probably be an abstract class, having no objects at all (although not a condition)
a service class. It can define some methods, which in nature do not belong to concrete objects but are used by other objects. Like some all-purpose mathematical operations, a service that returns a current time or similar. These methods can be static, so again no instances are needed.
We call those object stateless. As the name suggests, they have no state.
Referring to other answers/comments, even though every Java object implicitly extends Object, mind that Object has no fields. So even though every object has a runtime address and class attributes, for all practical purposes you can still consider some objects stateless.
Next, it is definitely not true that stateless objects serve no purpose! You can use stateless object for:
1) Grouping functions with similar functionality, similar to java.lang.Math, which groups mathematical functions.
2) Passing functionality as a parameter, e.g. Comparator<T> can be used to sort objects that do not implement Comparable<T>, and it definitely needs no state.
Stateless objects are somehow similar to immutable objects: their state can never be changed and therefore they are always thread-safe.
You may also want to see JEE Stateless Session Beans which differentiate between a converstional state and an instance state.
I am running findbugs on some code and it says the readObject(...) method must be private to be invoked for serialization/unserialization? Why? What is the problem if it is made public?
About readObject()/writeObject() being private, here's the deal: if your class Bar extends some class Foo; Foo also implements readObject()/writeObject() and Bar also implements readObject()/writeObject().
Now, when a Bar object is serialized or deserialized, JVM needs to call readObject()/writeObject() for both Foo and Bar automatically (i.e. without you needing to call these super class methods explicitly). However, if these methods are anything but private, it becomes method overriding, and JVM can no longer call the super class methods on the sub class object.
Hence they must be private!
In the modern Java implementations (at least JDK 6 through 10), the ObjectInputStream and ObjectOutputStream classes will only recognize readObject, readObjectNoData and writeObject methods if they are declared as private and NOT static.
(I couldn't find this stated explicitly in any of the documentation, but the restriction is clearly implemented in the code.)
So, irrespective of whether it is a good idea or not, FindBugs is correct in pointing out that a non-private readObject method is a bug. It won't be used.
The only reason I want to make this method public is to make it final so that inheriting objects cannot fiddle with it.
I don't think you should try to do that. Put a note in the class-level javadoc to say what you think that subclasses should and should not do. If someone chooses to implement a class ignoring that advice, it is their problem to deal with the consequences.
The problem with trying to force other people to implement subclasses in a particular way is that they may have a use-case that requires them to do things differently ... for reasons that you are not in a position to understand. It is a better idea to leave future developers with the freedom to do what they want, and let them take responsibility for the consequences.
I'm not sure why findbugs thinks it's a bug, but I can guess at two possible reasons. Making readObject public breaks encapsulation because the calling code has visibility into the internal structure of your class. Also, by making it public you force all derived classes to declare readObject as public. So unless the class is final, you're changing the contract for serialization.
I thought findbugs could provide rationale for most of its messages. Does it have anything to say about this?
There's no reason for you to call serialization methods such as readObject yourself, much less from another class. You should minimize the visibility of everything you can.
Edit: If you want subclasses to be able to change the behavior, make the method protected... that's acceptable.
In order for your method to be called by objectInputStream.readObject(), you must declare it private:
private void readObject(ObjectInputStream objectInputStream)
If you do not, your method will not be called (put a break point in there to prove this). Your code may appear to work but that is because the default serialization is being used.
You might be wanting to make this protected to allow for subclassing but this is not needed. The serialization process automatically calls the readObject of the base class prior to calling the readObject of the concrete class. This happens even if the concrete class does not make a call to:
objectInputStream.defaultReadObject();
...contrary to other posts I have read on the web. The same applies to the writeObject methods as well.
In java, is there ever a case for allowing a non-abstract class to be extended?
It always seems to indicate bad code when there are class hierarchies. Do you agree, and why/ why not?
There are certainly times when it makes sense to have non-final concrete classes. However, I agree with Kent - I believe that classes should be final (sealed in C#) by default, and that Java methods should be final by default (as they are in C#).
As Kent says, inheritance requires careful design and documentation - it's very easy to think you can just override a single method, but not know the situations in which that method may be called from the base class as part of the rest of the implementation.
See "How do you design a class for inheritance" for more discussion on this.
I agree with Jon and Kent but, like Scott Myers (in Effective C++), I go much further. I believe that every class should be either abstract, or final. That is, only leaf classes in any hierarchy are really apt for direct instantiation. All other classes (i.e. inner nodes in the inheritance) are “unfinished” and should consequently be abstract.
It simply makes no sense for usual classes to be further extended. If an aspect of the class is worth extending and/or modifying, the cleaner way would be to take that one class and separate it into one abstract base class and one concrete interchangeable implementation.
there a good reasons to keep your code non-final. many frameworks such as hibernate, spring, guice depend sometimes on non-final classes that they extends dynamically at runtime.
for example, hibernate uses proxies for lazy association fetching.
especially when it comes to AOP, you will want your classes non-final, so that the interceptors can attach to it.
see also the question at SO
This question is equally applicable to other platforms such as C# .NET. There are those (myself included) that believe types should be final/sealed by default and need to be explicitly unsealed to allow inheritance.
Extension via inheritance is something that needs careful design and is not as simple as just leaving a type unsealed. Therefore, I think it should be an explicit decision to allow inheritance.
Your best reference here is Item 15 of Joshua Bloch's excellent book "Effective Java", called "Design and document for inheritance or else prohibit it". However the key to whether extension of a class should be allowed is not "is it abstract" but "was it designed with inheritance in mind". There is sometimes a correlation between the two, but it's the second that is important. To take a simple example most of the AWT classes are designed to be extended, even those that are not abstract.
The summary of Bloch's chapter is that interaction of inherited classes with their parents can be surprising and unpredicatable if the ancestor wasn't designed to be inherited from. Classes should therefore come in two kinds a) classes designed to be extended, and with enough documentation to describe how it should be done b) classes marked final. Classes in (a) will often be abstract, but not always. For
I disagree. If hierarchies were bad, there'd be no reason for object oriented languages to exist. If you look at UI widget libraries from Microsoft and Sun, you're certain to find inheritance. Is that all "bad code" by definition? No, of course not.
Inheritance can be abused, but so can any language feature. The trick is to learn how to do things appropriately.
In some cases you want to make sure there's no subclassing, in other cases you want to ensure subclassing (abstract). But there's always a large subset of classes where you as the original author don't care and shouldn't care. It's part of being open/closed. Deciding that something should be closed is also to be done for a reason.
I couldn't disagree more. Class hierarchies make sense for concrete classes when the concrete classes know the possible return types of methods that they have not marked final. For instance, a concrete class may have a subclass hook:
protected SomeType doSomething() {
return null;
}
This doSomething is guarenteed to be either null or a SomeType instance. Say that you have the ability to process the SomeType instance but don't have a use case for using the SomeType instance in the current class, but know that this functionality would be really good to have in subclasses and most everything is concrete. It makes no sense to make the current class an abstract class if it can be used directly with the default of doing nothing with its null value. If you made it an abstract class, then you would have its children in this type of hierarchy:
Abstract base class
Default class (the class that could have been non-abstract, only implements the protected method and nothing else)
Other subclasses.
You thus have an abstract base class that can't be used directly, when the default class may be the most common case. In the other hierarchy, there is one less class, so that the functionality can be used without making an essentially useless default class because abstraction just had to be forced onto the class.
Default class
Other subclasses.
Now, sure, hierarchies can be used and abused, and if things are not documented clearly or classes not well designed, subclasses can run into problems. But these same problems exist with abstract classes as well, you don't get rid of the problem just because you add "abstract" to your class. For instance, if the contract of the "doSomething()" method above required SomeType to have populated x, y and z fields when they were accessed via getters and setters, your subclass would blow up regardless if you used the concrete class that returned null as your base class or an abstract class.
The general rule of thumb for designing a class hierarchy is pretty much a simple questionaire:
Do I need the behavior of my proposed superclass in my subclass? (Y/N)
This is the first question you need to ask yourself. If you don't need the behavior, there's no argument for subclassing.
Do I need the state of my proposed superclass in my subclass? (Y/N)
This is the second question. If the state fits the model of what you need, this may be a canidate for subclassing.
If the subclass was created from the proposed superclass, would it truly be an IS-A relation, or is it just a shortcut to inherit behavior and state?
This is the final question. If it is just a shortcut and you cannot qualify your proposed subclass "as-a" superclass, then inheritance should be avoided. The state and logic can be copied and pasted into the new class with a different root, or delegation can be used.
Only if a class needs the behavior, state and can be considered that the subclass IS-A(n) instance of the superclass should it be considered to inherit from a superclass. Otherwise, other options exist that would be better suited to the purpose, although it may require a little more work up front, it is cleaner in the long run.
There are a few cases where we dont want to allow to change the behavior. For instance, String class, Math.
I don't like inheritance because there's always a better way to do the same thing but when you're making maintenance changes in a huge system sometimes the best way to fix the code with minimum changes is to extend a class a little. Yes, it's usually leads to a bad code but to a working one and without months of rewriting first. So giving a maintenance man as much flexibility as he can handle is a good way to go.