Can nested generics be linked?

Is it possible to link nested generics / captures together?

I often have a problem finding a class map for a generic element of a specified class. In specific terms, I want something like this (no, T is not declared anywhere).

private Map<Class<T>, ServiceLoader<T>> loaders = Maps.newHashMap();

In short, I want loaders.put / to get semantics like this:

<T> ServiceLoader<T> get(Class<T> klass) {...}
<T> void put(Class<T> klass, ServiceLoader<T> loader) {...}

Is the following the best I can do? Should I live with the inevitable @SuppressWarnings("unchecked")somewhere along the line?

private Map<Class<?>, ServiceLoader<?>> loaders = Maps.newHashMap();
+3
source share
2 answers

, : , Class/ServiceLoader, T, T ?

, , . Map<Class<?>,ServiceLoader<?>>.

public class MyMap {
   private Map<Class<?>, ServiceLoader<?>> loaders 
      = new HashMaps<Class<?>, ServiceLoader<?>>();

   public<T> void put(Class<T> key, ServiceLoader<T> value) {
      loaders.put(key, value);
   }

   @SuppressWarnings("unchecked")
   public<T> T get(Class<T> key) { return (ServiceLoader<T>) loaders.get(key); }
}

@SuppressWarnings("unchecked") . , , , , , .

+6

- . , Maps.newHashMap(), , Google Guava, ForwardingMap.

public class Loader<T> extends ForwardingMap<Class<T>, ServiceLoader<T>> {

   private Map<Class<T>, ServiceLoader<T>> delegate = Maps.newHashMap();

}

, :

public class Loader<T> extends ForwardingMap<Class<T>, Class<T>> {

   private Map<Class<T>, Class<T>> delegate = Maps.newHashMap();

   @Override protected Map<Class<T>, Class<T>> delegate() {
      return delegate;
   }

   public static void main(String[] args) {
      Loader<Integer> l = new Loader<Integer>();

      l.put(Integer.class, Integer.class);

      // error
      l.put(Integer.class, String.class);
   }

}
0

Source: https://habr.com/ru/post/1739961/


All Articles