Я столкнулся с аналогичной проблемой: как указал Томек, вам понадобится специальный десериализатор, а также определенное поле JSON, которое вы будете использовать во время выполнения, чтобы решить, какой подкласс должен иметь экземпляр.
Рассмотрим следующий класс в качестве базового класса:
// Base class for a server sent event
public class ServerEvent
{
public static final String TYPEFIELDNAME = "eventType";
// Event type is used during deserialization to choose the right subclass
private final String eventType;
public ServerEvent(String eventType)
{
this.eventType = eventType;
}
public String toString()
{
return "eventType: " + eventType;
}
}
ServerEvent имеет два подкласса, каждый из которых с различными свойствами:
public class EventA extends ServerEvent
{
private static final String EVENTTYPE = "eventa";
private int data;
public EventA()
{
super(EVENTTYPE);
}
// Helper function to register this class with ServerEventDeserializer
public static void register(ServerEventDeserializer deserializer)
{
deserializer.registerEvent(EVENTTYPE, EventA.class);
}
public String toString()
{
return super.toString() + ", data = " + data;
}
}
public class EventB extends ServerEvent
{
private static final String EVENTTYPE = "eventb";
private String name;
public EventB()
{
super(EVENTTYPE);
}
// Helper function to register this class with ServerEventDeserializer
public static void register(ServerEventDeserializer deserializer)
{
deserializer.registerEvent(EVENTTYPE, EventB.class);
}
public String toString()
{
return super.toString() + ", name = " + name;
}
}
Два возможных входов могут быть следующие:
{ "eventType" : "eventa", "data" : 15 }
{ "eventType" : "eventb", "name" : "test" }
Это полиморфный десериализатор:
// This class handles the polymorphic deserialization of ServerEvent class
public class ServerEventDeserializer implements JsonDeserializer<ServerEvent>
{
// Gson engine
private Gson gson;
// Map of subclasses
private Map<String, Class<? extends ServerEvent>> eventRegistry;
public ServerEventDeserializer()
{
gson = new Gson();
eventRegistry = new HashMap<String, Class<? extends ServerEvent>>();
}
// Registers a ServerEvent subclass
public void registerEvent(String event, Class<? extends ServerEvent> eventInstanceClass)
{
eventRegistry.put(event, eventInstanceClass);
}
@Override
public ServerEvent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
try
{
// Get the JSON object
JsonObject commandObject = json.getAsJsonObject();
// Read the field named "ServerEvent.TYPEFIELDNAME"
JsonElement commandTypeElement = commandObject.get(ServerEvent.TYPEFIELDNAME);
// Query the eventRegistry map to instance the right subclass
Class<? extends ServerEvent> commandInstanceClass = eventRegistry.get(commandTypeElement.getAsString());
ServerEvent command = gson.fromJson(json, commandInstanceClass);
return command;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
Я написал минимальный рабочий пример, который можно загрузить here.
Спасибо за ответ! Я не могу посмотреть на количество параметров, поскольку два метода могут иметь одинаковое количество параметров. Они даже должны иметь точно такие же параметры. Можете ли вы разработать десериализацию методов? – anony115511
Хорошо позже. Но у меня вопрос, в чем разница между этими классами? Только реализация определенных методов? В таком случае их невозможно распознать. Затем вы можете просто добавить дополнительный параметр, например «имя» и в имя набора конструктора вашего конкретного класса. Это будет самое простое решение. Тогда десериализация будет легкой. – Tomek