Bounded class as parameter

86 Views Asked by At

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!

1

There are 1 best solutions below

1
On BEST ANSWER

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.