Home Ask Login Register

Developers Planet

Your answer is one click away!

Cheloute February 2016

Bounded class as parameter

I'm driving crazy with the bounded class...

I defined such a method :

protected <X> DataAccessResult<List<X>> executeQuery(final String query, final Class<X> elementType,Object... args)

And I want to call it with the following arguments: Query : a SQL query, what it actually does doesn't matter elementType : I need something like Map<String,Object>.class, because what I need to get is a DataAccessResult<List<Map<String,Object>>>

But Map<String,Object>.class doesn't compile, and Map.class doesn't allow me to have a DataAccessResult<List<Map<String,Object>>> as result type.

I mean :

DataAccessResult<List<Map>> x = executeQuery("Select * from table",Map.class, (Object[]) null);
DataAccessResult<Map<String,Object>>> y = (DataAccessResult<Map<String,Object>>>) x;

provoke a cast error and DataAccessResult<List<Map<String,Object>>> x = executeQuery("Select * from table",Map.class, (Object[]) null); doesn't work either..

What could be the correct syntax?

Thanks!

Answers


Robert Bräutigam February 2016

Short answer: you can not really do it. At least not in normal Java syntax. There are workarounds however.

The first is, you just explicitly specify X on the caller side this way:

protected <X> DataAccessResult<List<X>> executeQuery(final String query, Object... args)

this.<Map<String, Object>>executeQuery("Select * from table");

You could also pass in an object instead of a class, that can "carry" the generic parameters:

protected <X> DataAccessResult<List<X>> executeQuery(final String query, X prototype, Object... args)

executeQuery("Select * from table", new Map<String, Object>());

Both of these require no additional work, but are admittedly clumsy. The third option is to introduce a replacement for the Class<T> construct, which can carry generic parameters. This would word like this:

protected <X> DataAccessResult<List<X>> executeQuery(final String query, JavaType<X> type, Object... args)

executeQuery("Select * from table", map(String.class, Object.class));

Where JavaType could look like this:

public class JavaType<T> {
    public static <K, V> JavaType<Map<K, V>> map(Class<K> keyType, Class<V> valueType) {
        new JavaType<Map<K, V>>();
    }
}

This JavaType<T> class can be then extended with normal classes, lists, whatever you need. It could even carry the necessary class objects if you need them for reflection.

Post Status

Asked in February 2016
Viewed 3,686 times
Voted 4
Answered 1 times

Search




Leave an answer


Quote of the day: live life