7

... or at least pass in a specific class? Here is what I have right now:

private static invoice_response GetResponse(String jsonResponse)
{
    invoice_response deserialized = (invoice_response) JSON.deserialize(jsonResponse, invoice_response.class);
    return deserialized;
}    

Since I have to deserialized a bunch of things... I'd like to have the following with Generics or perhaps another way:

private static invoice_response GetResponse<T>(String jsonResponse)
{
    T deserialized = (T) JSON.deserialize(jsonResponse, T.class);
    return deserialized;
}   

Is this possible using Apex?

P.S. @MarkPond provided a solid attempt at the solution to this problem, but, alas, Apex only supports built in generics, thus I can't properly "genericize" this method.

3
  • @MarkMasterson The linked question does not address my concerns. It just talks about generics in general and does not address mention my specific case. Sep 2, 2014 at 21:39
  • @AngryHacker - Read the entire thread. Your answer is in there.
    – Eric
    Sep 3, 2014 at 0:25
  • It does say in there that they can't be used in interfaces... that doesn't preclude methods of course but I'm pretty sure it's a good indicator that they're not supported
    – Matt Lacey
    Sep 3, 2014 at 4:33

1 Answer 1

5

You could pass in the name of the type that can be used by the deserializer but unless these are sObjects you're going to be stuck on making the return generic and strongly typed.

private static List<sObject> GetResponse(String jsonResponse, String jsonType) {

    // get the type for deserialization
    Type dataType = Type.forName(jsonType);

    // deserialize into a generic sObject list return type
    List<sObject> deserialized = (List<sObject>)JSON.deserialize(jsonResponse, dataType);

    return deserialized;
}

It would be called like this:

List<sObject> objectsList = GetResponse('[{"name":"acme"}]', 'List<Account>');

List<Account> accountList = (List<Account>)GetResponse('[{"name":"acme"}]', 'List<Account>');

I would probably suggest using JSON.deserializeUntyped instead, though it becomes a bit less useful to have the helper method in this form.

private static Map<String, Object> GetResponse(String jsonResponse) {

    return (Map<String, Object>)JSON.deserializeUntyped(jsonResponse);

}

If you want to see a solid example of using this mechanism and how you might build your classes to help work with a concrete type, take a look at this answer:

Write a generic JSON-serializable Parameters class...

4
  • I'd argue it's cleaner to expect the Type object instead of the type's fully qualified name in your method arguments. There's nothing stopping passing around type tokens. Sep 3, 2014 at 2:53
  • The method doesn't return a list of anything. It just deserializes into a regular class object. How would I make it work for that scenario? Sep 3, 2014 at 6:02
  • @ca_peterson very true! Until apex supports generic return types, this pattern is generally useless in practical application.
    – Mark Pond
    Sep 3, 2014 at 7:54
  • 1
    @AngryHacker, I cannot provide you a solid solution to your issue as Apex does not support generic types in this manner. It is most critical for the return type. Today, you'll have to create a static method for each data type that you will return. In the future you may be able to return a generic type from a method such as this.
    – Mark Pond
    Sep 3, 2014 at 8:02

Not the answer you're looking for? Browse other questions tagged .