shau-lok / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

Support immutable objects #287

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
GSON should use Unsafe to instantiate objects without invoking the default 
constructor. That would permit GSON to support immutable objects, similarly to 
how Java serialization does it.

Original issue reported on code.google.com by jessewil...@google.com on 7 Feb 2011 at 11:01

GoogleCodeExporter commented 9 years ago
This may be an ugly syntax, but I'll propose it:

@DeserializationConstructor  
public MetaData(
  String shortDescription,
  String description,
  TaskType type) {
  ...
}

and

class X {
  @SerializedName("changeSets")
  private final List<Stuff> internalName;
  private final MetaData metadata;

  @DeserializationConstructor  
  public Task(
    @SerializedName("changeSets")
    List<Stuff> otherName,
    Metadata metadata) {
  }

Original comment by konigsb...@google.com on 7 Feb 2011 at 11:05

GoogleCodeExporter commented 9 years ago
Man I thought, "I'll just knock out something ugly and they'll love me." This 
is hard.

First I thought, the parameter names will suffice for mapping to JSON names. 
Nope - those don't exist. Then I thought, I can just use 
constructor.getParameterTypes. Nope -- that doesn't work either. Lots to do.

Original comment by konigsb...@google.com on 9 Feb 2011 at 5:50

GoogleCodeExporter commented 9 years ago
The "Unsafe" approach was implements in r723.

Original comment by joel.leitch@gmail.com on 14 Feb 2011 at 10:28

GoogleCodeExporter commented 9 years ago
The Unsafe approach doesn't work on google app engine.

Can we use the approach in Comment 1?  Ex. use an annotation to select a 
constructor, then SerializedName annotation to store the name mapping of the 
fields?

Ex. here's how Jackson do it:

 public class Point {
  private final int x, y;

  @JsonCreator
  public Point(@JsonProperty("x") int x, @JsonProperty("y") int y) {
   this.x = x;
   this.y = y;
  }
 }

Personally, I would like to be able to choose which annotations designate the 
name of fields and that select constructors.

I hope you can resurrect this issue, as jclouds code needs to work in google 
app engine, and the current approach doesn't work (and didn't *really* work 
anyway, as it cheats and can leave fields uninitialized or unvalidated as the 
intended immutable constructor is never used).

Original comment by adrian.f...@gmail.com on 29 May 2012 at 7:57

GoogleCodeExporter commented 9 years ago
Anything that requires a special compilation option is not a robust enough 
approach for inclusion in Gson.

The next best thing would be to provide a reusable class in extras package. We 
should consider writing writing a reusable TypeAdapterFactory that does this 
for all classes with DeserializationConstructor annotation.

Original comment by inder123 on 30 May 2012 at 4:21

GoogleCodeExporter commented 9 years ago
+1 to Inder's suggestion. It wouldn't be too much effort to make constructor 
deserialization work with TypeAdapterFactory.

Original comment by jessewil...@google.com on 30 May 2012 at 4:23

GoogleCodeExporter commented 9 years ago
ok. I'll work on a patch today.  thanks!

Original comment by adrian.f...@gmail.com on 30 May 2012 at 4:30

GoogleCodeExporter commented 9 years ago
Here's a start complete w/unit tests for deserializing.  what's left to do is:
  * implement serializing
  * weave in where unsafe is currently used
  * (probably separate issue) provide means to supply alternate annotations

Original comment by adrian.f...@gmail.com on 30 May 2012 at 6:38

Attachments:

GoogleCodeExporter commented 9 years ago
I'm going to hack on other stuff for the rest of the day.  if this looks 
alright, I can help complete it tomorrow.

Original comment by adrian.f...@gmail.com on 30 May 2012 at 6:44

GoogleCodeExporter commented 9 years ago
attached DeserializationConstructorAndReflectiveTypeAdapterFactory is a drop-in 
replacement for ReflectiveTypeAdapterFactory

Note that if you do replace, the following test fails:
CustomSerializerTest.testBaseClassSerializerInvokedForBaseClassFieldsHoldingSubC
lassInstances

I hope this is a good start and this code can work its way into gson!

Original comment by adrian.f...@gmail.com on 1 Jun 2012 at 12:30

Attachments:

GoogleCodeExporter commented 9 years ago
Any thoughts on how do deal with classes that you can't modify?  E.g. 
ImmutableList in Guava

Original comment by gak@google.com on 31 Aug 2012 at 5:41

GoogleCodeExporter commented 9 years ago
Er, how to

Original comment by gak@google.com on 31 Aug 2012 at 5:41