Java: De-Serialize a container of generic serializables? - java

I have different kinds of serializable ObjectState's that store state data for important application objects. I do this so I can persist these important objects arcoss application instatances. The user will sometimes need to group certain objects together into containers, so some of the ObjectState's are placed into an array of ObjectState's and passed to a ContainerState (just a serializable class that holds an array of generic types serializables).
My question is, how do I de-serialize the ContianerState and keep type integrity? I thought I could try something like:
public static ContainerState<V> inflateState(V v, Serializable state) throws ClassCastException {
return (ContainerState<V>)state;
}
But that won't even get past Eclipses' warning system. I also tried V.class to the same result. Is it even possible for me to achieve this?
EDIT 1:
I tried this, it seems to work, but I'm not sure if it's the best way. Any thoughts?
public static <cls extends Serializable> ContainerState<cls> inflateState(Class<? extends Serializable> cls, Serializable state) throws ClassCastException {
return (ContainerState<cls>)state;
}

This should at least compile:
public static <C extends Serializable> ContainerState<C> inflateState(Class<C> cls, Serializable state) throws ClassCastException {
return (ContainerState<C>)state;
}

Related

Class<SomeObject<?>> is NOT a superclass of Class<SomeObject<SpecificObject>>?

EDIT 1: According to this, despite SomeObject<?> being indeed a superclass of SomeObject<Foo>, Class<SomeObject<?>> is NOT a superclass of Class<SomeObject<Foo>>. The question on how to tackle this specific problem still persists. (adding a method to the Message<T> class that returns Class<Message<T>>, perhaps?)
Original question:
So basically I have a generic Message<T> class that implements a well known design pattern called Command pattern (with a twist: instead of building an object with a reference, the reference is passed as argument of the execute(T objectToCallMethodsOn)) and it looks something like this:
public abstract class Message<T> {
void execute(T obj); //e.g. DoSomethingOnFooMessage implements Message<Foo> to do something on a Foo object
}
so that I can do something like:
public DoSomethingOnFooMessage implements Message<Foo> {
#Override
void execute(Foo obj) {
obj.doSomething(); //doSomething is a method of the Foo class
}
}
Now, I also tried to make a MessageProcessor class with an internal map that maps (E is a type parameter) Class<Message<E>> to a object E executableObject (like Foo in the previous example) and with two methods: a handleMessage(Message<?> msg) that should do a dynamic instanceof of the Message (hence the need for the Class<> objects that let you do a dynamic instanceof and then a dynamic cast) and look for the right executableObject in the map to call the message's execute(E obj) on the right object (if it exists, otherwise the message is discarded), and a addProcessor() to add entries of e.g. Class<Message<Foo>>, Foo to the map:
public class MessageProcessor {
private final Map<Class<Message<?>>, Object> map;
public MessageProcessor() {
map = new HashMap<>();
}
public <E> void addProcessor(Class<Message<E>> messageClass, E executable) {
map.put(messageClass, executable);
}
...
}
So far that's what I wrote but the IDE complains that Class<Message<E>> was given but Class<Message<?>> was needed in addProcessor() and I don't know why; afaik, SomeClass<?> should be a superclass of any SomeClass<SpecificClass>, why isn't it the same for Class<SomeObject<?>> and Class<SomeObject<SpecificObject>>?
Sorry for the verbose question, other than asking a thing about superclassing of generics, I am also asking you guys for (perhaps) a different, more elegant way to do what I'm trying to do, which is find the runtime class of the message so that I can call its execute() with the object that I registered with the addProcessor() as its input.
Also, I reckon this could be easily solvable with raw types (ew)

Java generics in List return type on a method inherited from multiple interfaces

I'm currently working at a company that has a diverse set of modules. In that company if you want to provide module internals you provide it via a java interface, that hides the actual implementing type and gives an interface for the requesting module. Now I want to have one provider to be able to provide data for multiple modules that expose different fields or methods of the actual internal data.
Therefore I have an internal Object, which has some data and I have an interface for each module that needs access to some but not strictly all fields. Finally I have an external object that implements all those interfaces and holds an instance of the internal object to delegate the method calls:
public class InternalObject {
public int getA() { return 0; }
public int getB() { return 0; }
}
public interface ModuleXObject {
int getA();
}
public interface ModuleYObject {
int getA();
int getB();
}
public class ExternalObject implements ModuleXObject, ModuleYObject {
private InternalObject _internal;
public int getA() { return _internal.getA(); }
public int getB() { return _internal.getB(); }
}
Now that is all fine and dandy, but if I want to provide - lets say - repository methods for finding a list of said objects typed for the correct module, I run into problems with how I can achieve that. I would wish for something like the following:
public interface ModuleXObjectRepository {
List<ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List<ExternalObject> loadAllObjects() {
// ...
}
}
This doesn't compile saying the return type is incompatible.
So my question is, if it is possible to achieve something like that and if, how?
I should note that I tried some different approaches which I want to include for completeness and to portray their downsides (in my eyes).
Approach 1:
public interface ModuleXObjectRepository {
List<? extends ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<? extends ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List<ExternalObject> loadAllObjects() {
// ...
}
}
This approach is quite close to the solution I would prefer, but results in code like this:
List<? extends ModuleXObject> objects = repository.loadAllObjects();
Therefore requiring the user to include the "? extends" into each List-Declaration regarding to an invocation of loadAllObjects().
Approach 2:
public interface ModuleXObjectRepository {
List<ModuleXObject> loadAllObjects();
}
public interface ModuleYObjectRepository {
List<ModuleYObject> loadAllObjects();
}
public class ExternalObjectRepository implements ModuleXObjectRepository, ModuleYObjectRepository {
public List loadAllObjects() {
// ...
}
}
This approach just omits the generic in the ExternalObjectRepository and therefore reduces the type safety too much in my opinion. Also I haven't tested if this actually works.
Just to reharse, is there any possible way to define the loadAllObjects-method in a way that enables users to get lists that are typed with the objects for their respective module without
requiring "? extends" in the users code
degrading type safety in the repository implementation
using class/interface level generics
The challenge with allowing it to be typed as List<ModuleXObject> is that other code may hold is as a List<ExternalObject>.
All ExternalObject instances are ModuleXObject instances but the inverse is not true.
Consider the following additional class:
public class MonkeyWrench implements ModuleXObject{
//STUFF
}
MonkeyWrench instances are NOT ExternalObject instances but if one could cast a List<ExternalObject> to a List<ModuleXObject> one could add MonkeyWrench instances to this collection, and this causes a risk of run time class cast exceptions and ruins type safety.
Other code could very easily have:
for(ExternalObject externalObject:externalObjectRepository.loadAllObjects())
If one of those instances is a MonkeyWrench instance, run time class cast, which is what generics are meant to avoid.
The implication of ? extends ModuleXObject is that you can read any object from the collection as a ModuleXObject but you can't add anything to the collection as other code may have additional constraints on the collection that are not obvious/available at compile time.
I'd suggest in your case to use ? extends ModuleXObject as its semantics seem to align with what you want, namely pulling out ModuleXObject instances, e.g.
ModuleXObjectRepository repo = //get repo however
for(ModuleXObject obj : repo.loadAllObjects()){
//do stuff with obj
}

Composition over inheritance for RealmObjects with Gson serialization

I'm considering Realm as a database solution for various reasons, but the big one currently being the TransactionTooLargeException now being thrown in Nougat has made it so I have to rework my current database architecture, based on ActiveAndroid, which has its own annoying limitations. The difficulty is that Realm does not support inheritance (https://github.com/realm/realm-java/issues/761) and they don't seem in any particular hurry to get around to it. Instead, they recommend using composition over inheritance, but I can't figure out how to make that work with Gson/Json deserialization.
Example:
Superclass: Animal, with subclasses Dog and German Shepherd
public class Animal {
private int numLegs;
private boolean hasFur;
}
public class Dog extends Animal {
private String color;
private boolean canDoTricks;
}
public class GermanShepherd extends Dog {
public boolean isGuardDog;
public boolean isAtRiskOfHipDysplasia()
}
(Sorry, this is a super canned example, just to illustrate).
Now let's say the json for this looks like:
{
"numLegs" : 4,
"hasFur" : true,
"color" : "Black & Brown",
"canDoTricks" : true,
"isGuardDog" : true,
"isAtRiskofHipDysplasia" : false
}
Now, I cannot modify the Json because it's an API that's giving it to me.
Looking at this answer: https://stackoverflow.com/a/41552457/4560689, it appears it is possible in a very hacky way to make it sort of work, but the answer notes that there are limitations including that the serialization would be wrong. Since the server only talks in the json format that doesn't involve crazy composition, this presents a problem.
Can I write a custom Gson deserializer/serializer to make this work? If so, what would that look like? I basically need to be able to convert a json payload into up to N objects, where N - 1 objects are nested inside the base object.
So with composition (note this isn't necessarily "Realm" composition, just an example, since it looks like Realm has to use some weird form of interface-composition), I'd have a class like below:
public class GermanShepherd {
public Animal animal;
public Dog dog;
// Generate a bunch of delegate methods here
}
Am I barking up the wrong tree? It feels like Realm might not work for what I'm trying to do, and inheritance is built into the API I'm using in multiple places, and specifically in the objects I want to persist, so I have to either figure out a workaround or use another solution. ActiveAndroid (what I'm using now) is also a less than ideal solution and I'm sick to death of dealing with skirting around deadlocks, crashes, querying on background threads that now cause crashes if the data is too big to pass in an Intent, etc...all issues with SQLite. I'm open to solutions to my main question or to alternatives that would solve this problem. Thanks in advance for your help!
You should create a new RealmObject class for each flattened concrete class, and map your JSON representation to them.
To retain inheritance, you can simulate it by inheriting getters/setters from interfaces that inherit from one another.
public interface IAnimal extends RealmModel {
int getNumberOfLegs();
void setNumberOfLegs(int legs);
boolean getHasFur();
void setHasFur(boolean hasFur);
}
public interface IDog extends IAnimal {
String getColor();
void setColor(String color);
boolean getCanDoTricks();
void setCanDoTricks();
}
public interface IGermanShepherd extends IDog {
boolean getIsGuardDog();
void setIsGuardDog(boolean isGuardDog);
boolean getIsAtRiskOfHipDysplasia();
void setIsAtRiskOfHipDysplasia(boolean isAtRisk);
}
Because then you can do
public class GermanShepard
extends RealmObject
implements IGermanShepard {
private int numLegs;
private boolean hasFur;
private String color;
private boolean canDoTricks;
private boolean isGuardDog;
private boolean isAtRiskofHipDysplasia;
// inherited getters/setters
}
You can even make repository class out of it
public abstract class AnimalRepository<T extends IAnimal> {
protected Class<T> clazz;
public AnimalRepository(Class<T> clazz) {
this.clazz = clazz;
}
public RealmResults<T> findAll(Realm realm) {
return realm.where(clazz).findAll();
}
}
#Singleton
public class GermanShepardRepository extends AnimalRepository<GermanShepard> {
#Inject
public GermanShepardRepository() {
super(GermanShepard.class);
}
}
And then
#Inject
GermanShepardRepository germanShepardRepository;
RealmResults<GermanShepard> results = germanShepardRepository.findAll(realm);
But you can indeed merge them into one class and then give it a String type; parameter to know what type it originally was. That's probably even better than having all these GermanShepards.

Level of encapsulation in JAVA

I am working with a project and don't want to give access to the innermost classes. This is the class structure I am using,
// data types are not important unless mentioned
class One
{
protected propertyOne;
protected String id;
}
class Two
{
protected ArrayList<One> arrayOne;
protected String id;
}
class Three
{
protected ArrayList<Two> arrayTwo;
protected otherProperty;
}
Now, main class will instantiate Three and should use Two and One through member methods. If I return any of ArrayList through get function, all the data can be easily changed from anywhere. So instead of ArrayList<Two>, I am returning ArrayList<Two.id> and then another method is called with particular Two.id. This takes care of keeping ArrayLists hidden but generates lots of code and extra objects because of ArrayList<Two.id> and ArrayList<One.id>.
In C++, I would have made a const method with const return type to ensure no changes in ArrayList.
Is there any smart way in Java to keep ArrayLists hidden?
We have a similar issue with a hibernate based API. We wanted to make "accidential" change impossible, enforcing the use of services to keep the business logic in one place and enforcing some access control on the API level.
We did resolve this with proxies and a derived Readonly interface.
So if you have a property in Two, the getX method is declared in a ReadonlyTwo interface. Whenever you return a list of Two, you declare the list to be of ReadonlyTwo. The programmer can hack around this by learning the API and he will see, when the object is really Two and can be typecasted. If you want to avoid that, you would have to wrap a proxy around the real Two object, implementing the ReadonlyTwo interface.
If you now return the lists as immutable lists, your API is pretty safe from external modification, even down to the object level.
// data types are not important unless mentioned
class One implements ReadonlyOne
{
protected propertyOne;
protected String id;
}
class Two implements ReadonlyTwo
{
protected ArrayList<? extends ReadonlyOne> arrayOne;
protected String id;
}
class Three implements ReadonlyThree
{
protected ArrayList<? extends ReadonlyTwo> arrayTwo;
protected otherProperty;
}
Interfaces look like this (you did not add any getter/setter methods, so I make them up here):
interface ReadonlyThree {
List<? extends ReadonlyTwo>getArrayTwo();
}
Your application objects requires business methods to handle the modification of Two and One objects:
interface ThreeService {
ReadonlyTwo addTwo(p1, p2, p3) throws BusinessException;
void removeTwo(ReadonlyTwo twoRO) throws BusinessException;
List<? extends ReadonlyTwo>findTwoByPredicate(Predicate p) throws BusinessException;
}

Code repetition vs readablility

I have multiple services (in Spring MVC) that are children of a global Service. So I need to know about the best practice (or your opinions) with multiple methods with this example:
//Domain classes
public class MyParentObject{}
public class MyObj extends MyParentObject{}
//Services
public class MyParentObjectServiceImpl implements MyParentObjectService{
#Override
public MyParentObject findObjectByProp(String prop, String objectType){
//myCode (not abstract class)
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl implements MyObjectService{
private myObjType = "MyObj";
#Override
public MyObj findMyObjByProp(String prop){
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
And in this approach, I use calls like this:
MyObj foo = myObjService.findMyObjByProp(prop);
So I need to know if this approach is "better" or more apropiate that calling directly the parent method with the second parameter. E.g:
MyObj foo = (MyObj)myParentObjectService.findObjectByProp(prop, "MyObj");
..and avoiding the creation of second methods, more specific. It is important to know that the children services will be created anyway, because we have lot of code that is specific of a domain objects.
I have the idea that the first approach is better, because is more readable, but I need to support that decision with some documents, blog, or opinions to discuss this designs with my colleagues.
This looks like a tagged class hierarchy. It's difficult to comment on the value of this design in general without knowing the details. However, a slightly different approach that I would recommend is to generify your base class to gain a little bit of type safety.
In particular:
public /* abstract */ class MyParentObjectServiceImpl<T extends MyParentObject>
implements MyParentObjectService{
MyParentObjectServiceImpl(Class<T> type) { this.type = type; }
private final Class<T> type; // subclasses provide this
#Override
public T findObjectByProp(String prop){
//you can use type for object specific stuff
}
}
public class MyObjServiceImpl extends MyParentObjectServiceImpl<MyObj>
// You might not need this interface anymore
// if the only method defined is findMyObjByProp
/* implements MyObjectService */ {
MyObjServiceImpl() {
super(MyObj.class);
}
#Override
public /* final */ MyObj findMyObjByProp(String prop) {
return (MyObj) super.findObjectByProp(prop, this.myObjType);
}
}
You definitely gain in type safety (casting will only appear in the base class), you get rid of the "tags" (the strings that identify the different objects) and possibly reduce the number of classes/interfaces required to implement the whole hierarchy. I successfully used this approach several times. Note that this works best if the base class is abstract. Food for thoughts.

Categories