I have five classes:
Comment
,Paper
,WoundPaper
,Document
,WoundDoc
.
Comment
is a holder for text.
Paper
is empty and abstract class.
WoundPaper
extends Paper
and stores a String and an ArrayList of Comments
.
Document
is abstract class and stores ArrayList of <? extends Paper>
.
WoundDoc
extends Document
.
You can see those classes below:
Comment class:
public class Comment {
private final String text;
public static class Builder {
private final String text;
public Builder(String text) {
this.text = text;
}
public Comment build(){
return new Comment(this);
}
}
private Comment(Builder builder) {
this.text = builder.text;
}
public String getText() {
return text;
}
}
Paper class:
public abstract class Paper {
protected Paper(ArrayList<Comment> commentList) {
}
}
WoundPaper class:
public class WoundPaper extends Paper {
private final String imageUri;
private final ArrayList<Comment> commentList;
public static class Builder {
private final String imageUri;
private final ArrayList<Comment> commentList;
public Builder(String imageUri, ArrayList<Comment> commentList) {
this.imageUri = imageUri;
this.commentList = commentList;
}
public WoundPaper build() {
return new WoundPaper(this);
}
}
private WoundPaper(Builder builder) {
super(builder.commentList);
this.imageUri = builder.imageUri;
this.commentList = builder.commentList;
}
}
Document class:
public abstract class Document {
private final ArrayList<? extends Paper> paperList;
protected Document(ArrayList<? extends Paper> paperList) {
this.paperList = paperList;
}
}
WoundDoc class:
public class WoundDoc extends Document {
public static class Builder {
private final ArrayList<WoundPaper> paperList;
public Builder(ArrayList<WoundPaper> paperList) {
this.paperList = paperList;
}
public WoundDoc build() {
return new WoundDoc(this);
}
}
private WoundDoc(Builder builder) {
super(builder.paperList);
}
}
Now I have to create an instance of WoundDoc
and convert it to JSON string by Gson.This is a sample code to do that:
Comment comment = new Comment.Builder("comment").build();
ArrayList<Comment> commentList = new ArrayList<Comment>();
commentList.add(comment);
commentList.add(comment);
WoundPaper woundPaper = new WoundPaper.Builder("some Uri", commentList).build();
ArrayList<WoundPaper> woundPaperList = new ArrayList<WoundPaper>();
woundPaperList.add(woundPaper);
woundPaperList.add(woundPaper);
WoundDoc woundDoc = new WoundDoc.Builder(woundPaperList).build();
System.out.println("woundDoc to JSON >> " + gson.toJson(woundDoc));
But output is strange:
woundDoc to JSON >> {"paperList":[{},{}]}
As I displayed before,WoundDoc
stores list of WoundPaper
and each WoundPaper
stores list of comment
s.But why there is no comment
in output?
When gson goes to serialise the WoundDoc
all it can tell is that there is a List
of two objects of type something which extends Paper
(List<? extends Paper>
); the specific type is unknown. As Paper
has no fields for gson to work with it can only say that there are two entries within that list, but as they are the type Paper
, which has no fields, there is no way to work out how to serialize those objects.
A way to resolve this is to pass type from your implementations to the abstract classes so that when gson inspects them it can see which class the objects it encounters are instances of, and so work out how to serialise them.
Update Document to take a type parameter:
public abstract class Document<T extends Paper> {
private final ArrayList<T> paperList;
protected Document(ArrayList<T> paperList) {
this.paperList = paperList;
}
}
Update WoundDoc to pass type to Document:
public class WoundDoc extends Document<WoundPaper> {
Another way to resolve it if you are unable to make the above changes would be to write a custom serializer for WoundDoc
Personally I'd use the first solution and pass type, because I'm lazy and writing a custom serializer is more effort
edit: Minor shout out to jackson which will throw an exception if you try to serialise something and it cannot work out how to do it.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments