0

I need to make a container object, in which one field act as a placeholder.

public static class Person {
        String name;
        Object data;        //Placeholder for custom type
}

This container type (Person) is used to send json data, which is de/serialized as shown in the code below.

import com.google.gson.Gson;

public class Main {

    public static class Address {
        String city;
        public Address(String city) {
            this.city = city;
        }
    }

    public static class Person {
        String name;
        Object data;        //Placeholder for custom type

        public Person(String name, Object data) {
            this.name = name;
            this.data = data;
        }
    }

    public static void main(String[] args) {
        Address addr = new Address("BBB") ;
        Person person = new Person("AAA", addr);

        Gson gson = new Gson();
        String json = gson.toJson(person);
        System.out.println("json = " + json);

        Person person2 = gson.fromJson(json, Person.class);
        System.out.println("person2  name = " + person2.name);
        System.out.println("person2  address = " + person2.data);
        Address addr2 = (Address)  person2.data;
        System.out.println("address  city = " + addr2.city);
    }
}

2 Questions:

  1. Is using Object this way is a good practice. There is no relation between types goes into the field (data), so not sure interface is viable.

  2. It throws error at the end. May be because, Gson cannot figure out the underlying type.

    json = {"name":"AAA","data":{"city":"BBB"}}  
    person2  name = AAA  
    person2  address = {city=BBB}  
    Exception in thread "main" java.lang.ClassCastException: 
    

    java.util.LinkedHashMap cannot be cast to Main$Address at Main.main(Main.java:33)

EDIT:

Based on the answers below, use of class name misguide the intention behind my question. Instead of Person, say I wanted to model a webresponse and call it Response. This object can be of any type.

say if you call the API /api/person/1 , you get below response
Response {
  String message
  Object value //type is Person
}

if you call an API /api/student/2
Response {
 String message
 Object value //type is Student
}

without using reflection at my part, any way to model the Response object so it accept any object as value and correctly marshall to the underlying type. Anonymous type (a throwaway class without type explosion) could be an option, which I read java doesn't have. Not sure how to use Generics in this context as one answer suggests.

Based on this answer, type erasure may make it not suitable to use generics. Using generics with GSON

Community
  • 1
  • 1
bsr
  • 57,282
  • 86
  • 216
  • 316
  • Why do you need a custom type? – StarPinkER Jan 29 '13 at 06:59
  • If you insist on doing it wrong, you could write a custom deserializer that casts whatever it is you actually have to an `Object` ... *why* you would want to do that is unclear, but that's how you would need to do it. You don't have an `Object` in your JSON, you have a specific type of thing. – Brian Roach Jan 29 '13 at 20:44

3 Answers3

1

Why not use Map like this:

public static class Person {
    String name;
    Map data;        //Placeholder for custom type
}

Map can compatible will with json.

lichengwu
  • 4,277
  • 6
  • 29
  • 42
0

Is using Object this way is a good practice. There is no relation between types goes into the field (data), so not sure interface is viable.

No, use generics.

It throws error at the end. May be because, Gson cannot figure out the underlying type.

Also, use generics to avoid .

TheWhiteRabbit
  • 15,480
  • 4
  • 33
  • 57
0

I am keeping it as JsonElement (from Gson), which then unmarshall to the correct type.

bsr
  • 57,282
  • 86
  • 216
  • 316