Serializable by extending with empty constructor? - java

TLDR: Is there a way to force to a subclass to have an empty constructor when the super does not?
I need to be to initialize a non-serializable class, TravelTimeDataArray, from a serialized data container. The TravelTimeDataArray cannot be serialized because it does not implement the Serializable interface, lacks an empty constructor, and uses a non-serializable field of type Link.
public class TravelTimeDataArray implements TravelTimeData {
private final double[] timeSum;
private final int[] timeCnt;
private final double[] travelTimes;
private final Link link; //I'm not serializable
public TravelTimeDataArray(final Link link, final int numSlots) {
this.timeSum = new double[numSlots];
this.timeCnt = new int[numSlots];
this.travelTimes = new double[numSlots];
this.link = link;
resetTravelTimes();
}
//getters and setters
}
My first thought was to extend this as a serializable class. Instead of using a Link, I can use a serializable String of it's ID attribute and add the empty constructor.
public class SerialTravelTimeDataArray extends TravelTimeDataArray implements java.io.Serializable{
private final String linkId = null; // I am serializable
public SerialTravelTimeDataArray(){ }
public SerialTravelTimeDataArray(TravelTimeDataArray ttDA){
// intialize me using ttDA's data
}
// Methods to serialize the fields.
// Methods to populate super's fields from the deserialized data containers
}
Since the super does not have an empty constructor, I get an error with the subclass's empty constructor. Is there a way to force to a subclass to have an empty constructor when the super does not?

According to The Serializable Interface:
A Serializable class must do the following:
Implement the java.io.Serializable interface
Identify the fields that should be serializable (Use the serialPersistentFields member to explicitly declare them serializable
or use the transient keyword to denote nonserializable fields.)
Have access to the no-arg constructor of its first nonserializable superclass
A no-arg constructor of a object's first nonserializable superclass is need to have access because it will be called while deserializing the object. Otherwise, an exception will be thrown. Note that serializing a object do not call its superclass's default constructor and no exception will be thrown.
If extending a class is not a must, you can consider using encapsulation like follows:
public class Foo implements Serializable {
private final double[] timeSum;
private final int[] timeCnt;
private final double[] travelTimes;
private final String linkId;
private final transient TravelTimeDataArray ttDA;
public Foo(TravelTimeDataArray ttDA) {
this.ttDA = ttDA;
this.timeSum = ttDA.getTimeSum();
this.timeCnt = ttDA.getTimeCnt();
this.travelTimes = ttDA.getTravelTimes();
this.linkId = ttDA.getLink().getId();
}
// Methods
}
If you do not need to access TravelTimeDataArray in your class, you can skip the field transient TravelTimeDataArray ttDA. Hope this can help.

Related

Why subclasses inherit private fields?

I'm creating a new class which is vehicle. I'm expecting the only protected variables inherit to subclasses. But when I try to create Constructor with IDE, it is also using superclasses private variables? -Which is private String vehicleName- I'm not clearly understanding this situation. Shouldn't I use auto Concstructor?
public class Vehicle {
protected int capacityOfPassengers;
protected String mapOfRoute;
private String vehicleName;
public Vehicle(int capacityOfPassengers, String mapOfRoute,
String vehicleName) {
this.capacityOfPassengers = capacityOfPassengers;
this.mapOfRoute = mapOfRoute;
this.vehicleName = vehicleName;
}
}
public class LandVehicle extends Vehicle {
private String brand;
private int priceModel;
public LandVehicle(int capacityOfPassengers, String mapOfRoute,
String vehicleName, String brand, int priceModel) {
super(capacityOfPassengers, mapOfRoute, vehicleName);
this.brand = brand;
this.priceModel = priceModel;
}
}
Generally, a class has a default constructor, taking no arguments, IF no constructor has been provided by you.
When you subclass Vehicle with your LandVehicle, your LandVehicle is a type of Vehicle. This means that it inherits methods and field from its superclass, even if they are private. For the class LandVehicle these members are just not visible, but they are still present - otherwise it couldn't function properly. The private keyword is an access modifier, that changes visibility to the caller.
As a result, to instantiate a LandVehicle, you also must provide the required attributes of its superclass Vehicle (since there is no default, no-arg constructor in Vehicle). In your example, a LandVehicle without a name (from Vehicle) wouldn't make sense, since a LandVehicle is a Vehicle, which requires a name.
You cannot access vehicleName from LandVehicle. You just pass some string parameter to super constructor, and the super constructor sets the vehicleName. For example, you can't initialize this field inside LandVehicle class as this.vehicleName = vehicleName.

GWT-Jackson-APT not ignoring interface object from serialization

I have a class object that contains an interface variable used for callbacks that I don't want serialized into the JSON. I have attempted to use the #JsonIgnoreProperties() annotation to make it ignore the interface variable, but so far no luck. The pre-processor is choking with a IllegalArgumentException Couldn't make a guess for CallbackRun...
The interface looks generally like:
public interface callbackRun {
void runOnFinish();
}
With the broad strokes shape of my class defined as:
#JSONMapper
#JsonIgnoreProperties(ignoreUnknown=true)
public class itemInventory {
public static itemInventory_MapperImpl MAPPER = new itemInventory_MapperImpl();
private static final List<item> itemList = new ArrayList<>();
private callbackRun responseHandler = null;
/ * other variables, getters setters here */
}
What is the best method of getting GWT-jackson-APT to ignore this interface? Or do I have to completely redefine all my objects to remove my callback function references?
You can use #JsonIgnore by annotating the field
#JSONMapper
public class itemInventory {
public static itemInventory_MapperImpl MAPPER = new itemInventory_MapperImpl();
private static final List<item> itemList = new ArrayList<>();
#JsonIgnore
private callbackRun responseHandler = null;
/ * other variables, getters setters here */
}
The field will not be serialized when writing object to JSON and it will be ignored when reading object from JSON. You can always check the generated mappers and you will see a method initIgnoredProperties in the generated deserializer, also the ignored field will not be included in the generated serializer.

What is the correct way to initialize fields of Action classes in Struts 2?

I have a class which I am using to store data that I retrieve from a database which has objects as fields.
I want to initialize the objects when the class is instantiated to avoid null pointer problems.
I thought I read somewhere that it should not initialize the fields in the field declaration because it may cause problems for Struts (but I can't find the statement now), so I am initializing the fields in the constructor.
My question is:
Does it matter which way you do it? Or should you not do it at all and only put in the new objects after you instantiate the class? In other words should I define my class like this:
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(){
projectInfo = new ProjectInfo();
partyInfo = new PartyInfo();
requestTableInfo = new RequestTableInfo();
partyRequestInfo = new PartyRequestInfo();
}
followed by getters and setters or like this.
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo = new ProjectInfo();
private PartyInfo partyInfo = new PartyInfo();
private RequestTableInfo requestTableInfo = new RequestTableInfo();
private PartyRequestInfo partyRequestInfo = new PartyRequestInfo();
public MenuView(){ }
followed by getters and setters or like this:
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(){}
followed by getters and setters and then instantiate it like this:
MenuView menu = new MenuView();
menu.setProjectInfo(new ProjectInfo);
Any of the methods above would work but this would be best. The whole point of initializing a class is to avoid null referenced of course and initialize them with preferred values as shown below.
Adding getters and setters would work just fine from there
public class MenuView implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private ProjectInfo projectInfo;
private PartyInfo partyInfo;
private RequestTableInfo requestTableInfo;
private PartyRequestInfo partyRequestInfo;
public MenuView(int a, int b, int c, int d){
projectInfo = new ProjectInfo(a);
partyInfo = new PartyInfo(b);
requestTableInfo = new RequestTableInfo(c);
partyRequestInfo = new PartyRequestInfo(d);
}
I read somewhere that you should not initialize the fields in the field declaration because that may cause problems for Struts (but I can't find the statement now)
No, not that I know
so I am initializing the fields in the constructor.
You can, but you're not forced to. I never use constructors on actions (I almost never use constructors at all, since I'm using Java EE 6+ and CDI, and in constructors the #Injected objects have not been injected yet - I use a #PostConstruct method instead, when necessary), but that's up to you, it's not a rule.
My question is does it matter which way you do it?
No
Or should you not do it at all and only put in the new objects after you instantiate the class?
Struts2 will handle the nulls for you in the JSP. The only NullPointerExceptions you must handle are on the Java side, so just check for null, or instantiate the objects in the declaration, and don't worry about it anymore.
Just remember that Struts2 will need a no-arg constructor to instantiate beans with JSP values.
It doesn't matter for Struts2, only sufficient that a ModelDriven object you should create yourself (if you are using ModelDriven interface).
The framework will create the objects if they are null when the form is submitted. This option is enabled by default. The magic is performed by the params interceptor which is using OGNL under hoods to populate the model from parameters passed to the action.
While this interceptor is being invoked, a flag
(ReflectionContextState#CREATE_NULL_OBJECTS) is turned on to ensure
that any null reference is automatically created - if possible. See
the type conversion documentation and the InstantiatingNullHandler
javadocs for more information.
More or less this feature is documented under com.opensymphony.xwork2.conversion.NullHandler.
The beans should comply a JavaBeans spec., so they could be instantiated by the Struts2 framework (if you want to learn more about JavaBeans, see this post What is a JavaBean exactly).

Overriding class signature in java

I have a class as follows in a .jar file (library file):
class A{
//someimplementation
}
I would like to make it to implements Serializable interface as follows:
class A implements Serializable {
//the same implementation as present in classA
}
I do not want to decompile the jar file, changing the class signature and then archiving it again after compilation.
Is there any way like writing hooks to achieve this? Kindly provide any pointers/suggestions.
My ultimate aim is to achieve implementing Serializable interface without modifying the jar file.
You can probably achieve this using Serialization Proxy Pattern (Effective Java 2nd edition Item 78)
A few links about the Pattern :
http://jtechies.blogspot.com/2012/07/item-78-consider-serialization-proxies.html
http://java.dzone.com/articles/serialization-proxy-pattern
Follow up: instance control in Java without enum
Make a new class that extends A and is Serializable. In order to avoid serialization errors, however, because A isn't serializable, you need to make a SerializationProxy that creates a new instance via constructor or factory method instead of the normal Java Serialization mechanism of explicitly setting the fields outside of any constructor.
public class MySerializableA extends A implements Serializable{
private final Foo foo;
private final Bar bar;
...
private Object writeReplace() {
return new SerializationProxy(this);
}
//this forces us to use the SerializationProxy
private void readObject(ObjectInputStream stream) throws InvalidObjectException {
throw new InvalidObjectException("Use Serialization Proxy instead.");
}
//this private inner class is what actually does our Serialization
private static class SerializationProxy implements Serializable {
private final Foo foo;
private final Bar bar;
...
public SerializationProxy(MySerializableA myA) {
this.foo = myA.getFoo();
this.bar = myA.getBar();
...//etc
}
private Object readResolve() {
return new MySerializableA(foo, bar,...);
}
}
}
The only downside is when you want to serialize an A, you will have to wrap it in a MyA. but when deserializing, the cast to A will work fine.

Any way to generate fully initialized constructor automatically by Eclipse?

Using Eclipse
For any Class we can automatically
Generate Setters an Getters
Generate Delegate Methods
Generate hashCode() and equals()
Generate toString()
Generate Constructor using Fields
Generate Constructor From Superclass
Like that
Any way to generate
Fully initialized Constructor
(Constructor without any parameters that initialized all non-primitive fields)
For example
If my class as that
public class MyClass {
private String id;
private String code;
private MyClass1 myClass1;
private MyClass2 myClass2;
}
Generated Fully initialized Constructor will be
public class MyClass {
private String id;
private String code;
private MyClass1 myClass1;
private MyClass2 myClass2;
// Fully initialized Constructor
public FlightScheduleRequest() {
this.myClass1 = new MyClass1();
this.myClass2 = new MyClass2();
}
}
Its invalid requirement
Thanks to #Jayan note
If MyClass1 or MyClass2 does not have the default constructor,
but takes arguments for its constructor
So the initialization of them will be invalid
this.myClass1 = new MyClass1(); // The constructor MyClass1() is undefined
this.myClass2 = new MyClass2(); // The constructor MyClass2() is undefined
There is an option there to generate constructor using fields.
Select the fields which you want the initialization for and you are done.

Categories