James Larkin
James Larkin

Reputation: 621

How can I make a method accept a class type variable in Java?

I've got the following method:

public <T> T deserialise(String payload, Class<T> expectedClass) {
    try {
        return mapper.readValue(payload, expectedClass);
    } catch (IOException e) {
        throw new IllegalStateException("JSON is not valid!", e);
    }
} 

that I can call using deserialise("{\"foo\": \"123\"}", Foo.class).

What type shall I use if I want to create a map from String to Class and then iterate over this map to deserialise the strings into objects?

E.g., I want something similar to:

Map<String, Class?> contents = ImmutableMap.of(
   "{\"foo\": \"123\"}", Foo.class,
   "{\"bar\": \"123\", \"bar2\": \"123\"}", Bar.class
);

And then I want to be able to:

for (Map.Entry<String, Class?> e : contents.entrySet) {
   Class? obj = deserialise(e.getKey(), e.getValue());
}

What should I put instead of Class??

Update:

ObjectMapper objectMapper = new ObjectMapper();

Map<String, Class<?>> contents = ImmutableMap.of(
        "{\"foo\": \"123\"}", Foo.class,
        "{ \"color\" : \"Black\", \"type\" : \"BMW\" }", Bar.class
);

for (Map.Entry<String, Class<?>> e : contents.entrySet()) {
    try {
        Object obj = objectMapper.readValue(e.getKey(), e.getValue());
        System.out.println(obj);
    } catch (IOException ex) {
        ex.printStackTrace();
    }
}

Update #2:

ObjectMapper objectMapper = new ObjectMapper();

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
T typeClass = Foo.class; // TODO: fix syntax error

try {
    Class<?> obj = objectMapper.readValue(json, typeClass); // TODO: fix error and cast obj to Foo.class using typeClass
} catch (IOException e) {
    e.printStackTrace();
}

Upvotes: 0

Views: 37

Answers (1)

Sweeper
Sweeper

Reputation: 271105

Your syntax is very close!

You should use Class<?>. The <?> is known as a generic wildcard.

Map<String, Class<?>> contents = ImmutableMap.of(
   "{\"foo\": \"123\"}", Foo.class,
   "{\"bar\": \"123\", \"bar2\": \"123\"}", Bar.class
);


for (Map.Entry<String, Class<?>> e : contents.entrySet) {
   Object obj = deserialise(e.getKey(), e.getValue());
}

Note that obj should not be of type Class<?> because deserialise returns T, not Class<T>.

Upvotes: 1

Related Questions