guochaiqi / google-gson

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

Allow serialization of anonymous and local classes #298

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

        Gson gson = new Gson();
        String json = gson.toJson(new Object() {
            String url = "http://localhost:10080/live/list";
            String[] names = new String[] {"dsc0001","dsc0002","dsc0003"};
        });
        System.out.println(json);

What is the expected output?
{"url":"http://localhost:10080/live/list","name":[{"dsc0001","dsc0002","dsc0003"
]}

What do you see instead?
blank line

What version of the product are you using? On what operating system?
1.6

Please provide any additional information below.
I understand that there are default exclusion strategies that prevent the 
serialization of objects belonging to an anonymous or local class, but it would 
be great if these could be bypassed to allow the above notation.

Original issue reported on code.google.com by robby...@gmail.com on 17 Mar 2011 at 2:14

GoogleCodeExporter commented 9 years ago
I have the same doubt. Are there any specific reasons why anonymous or local 
classes should be excluded?

I tried to disable the DEFAULT_ANON_LOCAL_CLASS_EXCLUSION_STRATEGY. It does not 
seem producing any problems

Original comment by lindap...@gmail.com on 14 Apr 2011 at 2:43

GoogleCodeExporter commented 9 years ago
And inner class will trigger problems using a type adapter is specified for the 
class since it generated an implicit reference to the outer class/instance 
which causes a circular reference. I do not recall the reason as to why we skip 
anonymous classes.

I will discuss this with Inder, but I do think that this is a valid feature 
that we should support.

Original comment by joel.leitch@gmail.com on 16 Apr 2011 at 5:59

GoogleCodeExporter commented 9 years ago
Issue 196 has been merged into this issue.

Original comment by joel.leitch@gmail.com on 16 Apr 2011 at 9:54

GoogleCodeExporter commented 9 years ago
Issue 346 has been merged into this issue.

Original comment by limpbizkit on 2 Oct 2011 at 3:38

GoogleCodeExporter commented 9 years ago
I respectfully disagree.

I'm doing something like this.

I have an interface, TFlat. I registered a custom serializer for that interface.

I have:

class O {
  TFlat p = new TFlat(){ int field1 = 3; int field2 = 4; }
  ...
}

And I'm trying to serialize an instance of O.

May be the exclusion strategy should pass out anonymous/local classes that 
would have be serialized in a custom way?

Thanks,
  Pawel.

Original comment by pawel.ve...@gmail.com on 12 Jan 2012 at 8:58

GoogleCodeExporter commented 9 years ago
Pawel, that's interesting I'll take a look. What do you think should happen 
when this is deserialized?

Original comment by limpbizkit on 13 Jan 2012 at 2:35

GoogleCodeExporter commented 9 years ago
Jesse,

I don't think this is particularly useful for deserializing.
If we were to stretch this, deserialization can see that the field is 
initialized, and if the incoming JSON fragment is an object, map the properties 
of the fragment to the fields of the object. IMO, right now, GSon always 
attempts to instantiate classes that are declared for each field (or use a 
custom deserializer to do so).

custom deserialization can create its own anonymous class that will implement 
TFlat. It would need to know the field location (somehow indicate where the 
field will go after deserialization), though, which is, to my knowledge, is not 
something GSon supports either. But I'm still on 1.7, haven't checked out all 
the 2.x goodies.

Original comment by pawel.ve...@gmail.com on 13 Jan 2012 at 5:02

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Interestingly enough, you can create instances of anonymous objects.
However, such instances will not be "attached" to the outer class, yet they are 
legal. Attempting to reference parent class will simply return null. Obvious 
problem is, of course, that there is no way to declare a field of anonymous 
class.

Here is the Groovy fragment I ran to test this:

interface T {
}
class P {
  int out = 13;
  T z = new T() {
    int k;
    {
        System.out.println("Anonymous <init>...");
        P parent = P.this;
        if (parent == null) { System.out.println("No Parent!"); }
        else { System.out.println(parent.out) }; 
    }
  };
}
P p = new P();
Class<T> cc = p.z.getClass();
System.out.println(cc.getName());
T another = cc.newInstance();
---
output:
Anonymous <init>...
13
P$1
Anonymous <init>...
No Parent!
Result: P$1@1567ee3

Original comment by pawel.ve...@gmail.com on 13 Jan 2012 at 5:10

GoogleCodeExporter commented 9 years ago

Original comment by limpbizkit on 11 Apr 2012 at 8:50

GoogleCodeExporter commented 9 years ago
We still use gson-1.3 due to this issue...

Today I found http://code.google.com/p/google-gson/issues/detail?id=96 in our 
logs.
The bug fixed in 1.4++, but we can't move to fresh version of gson since we 
have a lot of inner/local classes to serialize.

Original comment by stanisla...@gmail.com on 22 Jan 2013 at 12:02

GoogleCodeExporter commented 9 years ago
Same here. Even though I love GSON simplicity and extensibility, but inability 
to serialize anonymous classes simply kills the practical usability of this 
great library!

The use case I'm talking about is very simple and widely used. Image you have 
class Car:
public class Car {
   String name;
   String color;
}

Let's create 2 instances using different code-style:

   Car car1 = new Car();
   car1.name = "BMW";
   car1.color = "Red";

   Car car2 = new Car() {{
      name = "Nissan";
      color = "Gold";
   }}

car2 object has the same number of fields and from logical perspective it is of 
the same type than car1. The anonymous Car subclass created for the car2 
instance can be safely ignored in this case as it doesn't add anything to the 
car2 that car1 wouldn't have. So why would Gson refuse processing car2?

Original comment by alexande...@gmail.com on 6 Feb 2013 at 5:24

GoogleCodeExporter commented 9 years ago
Don't use double brace initialization. It prevents serialization and Gson is 
designed for symmetric serialization and serialization.

Original comment by limpbizkit on 7 Feb 2013 at 1:02

GoogleCodeExporter commented 9 years ago
jackson can do this:
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
        String result=mapper.writeValueAsString(x);
why gson not?

Original comment by che...@gmail.com on 21 Nov 2013 at 2:55