public class MyClass<T> {
private Map<Class<?>, Object> member;
public <E> void putEnumSet(Class<E> enumSetType, E enumSet) {
this.member.put(enumSetType, enumSetType.cast(enumSet));
}
public <E> E getEnumSet(Class<E> enumType) {
return enumType.cast(this.member.get(enumType));
}
};
public enum Category {
// ...
};
The member in MyClass is used to store several kinds of EnumSet with different Enum type. While implementing relative methods, I meet some problems: when I try to call the method like this:
public static void main(String[] args) {
EnumSet<Category> set = EnumSet.noneOf(Category.class);
MyClass<Word> newClass = new MyClass<Word>();
newClass.putEnumSet(set.getClass(), set);
}
Here comes the error:
The method putEnumSet(Class<E>, E) in the type MyClass<Word> is not applicable for the arguments (Class<capture#1-of ? extends EnumSet>, EnumSet<Category>)
How to deal with this problem? I think it may come from raw type or type erasure, but I do not know the main reason. Thanks.
How to deal with this problem?
E extends EnumSet<E>
This is very confusing as it says you have to have a element E which must extend EnumSet<E> i.e. you need an element type which is itself an EnumSet of E
You have a problem that all EnumSet classes are the same at runtime. I.e. there is only one EnumSet.class. You are better off recording the class of elements.
public class MyClass {
private Map<Class, Set> member;
public <E> void putEnumSet(Class<E> elementType, Set<E> enumSet) {
this.member.put(elementType, enumSet);
}
public <E> Set<E> getEnumSet(Class<E> elementType) {
return (Set<E>) this.member.get(elementType));
}
};
Class objects can be difficult to use. As you have noticed, they're not easy to use with generic types because due to type erasure EnumSet<Category>.class is not legal code. It would be impossible to use your approach to store EnumSets for different Enums because there is only one Class object for all EnumSets, namely EnumSet.class.
One solution I have found to this is to replace Class<?> with my own key object. Here is a complete program demonstrating this approach.
public class Main {
public enum Shape { SQUARE, CIRCLE, TRIANGLE }
// Here you would instantiate all the keys you will need.
public static final ClassKey<String> STRING_KEY = new ClassKey<String>();
public static final ClassKey<EnumSet<Shape>> SHAPE_SET_KEY = new ClassKey<EnumSet<Shape>>();
public static final class ClassKey<T> { private ClassKey() {} }
private Map<ClassKey<?>, Object> member = new HashMap<ClassKey<?>, Object>();
public <E extends Enum<E>> void putEnumSet(ClassKey<EnumSet<E>> enumSetType, EnumSet<E> enumSet) {
this.member.put(enumSetType, enumSet);
}
public <E extends Enum<E>> EnumSet<E> getEnumSet(ClassKey<EnumSet<E>> enumType) {
return (EnumSet<E>) member.get(enumType);
}
public static void main(String[] args) {
Main main = new Main();
EnumSet<Shape> enumSet = EnumSet.allOf(Shape.class);
main.putEnumSet(SHAPE_SET_KEY, enumSet);
EnumSet<Shape> shapes = main.getEnumSet(SHAPE_SET_KEY);
System.out.println(shapes);
}
}
One major drawback to this approach is that you have to have a fixed bank of ClassKey objects. It would not work to create these objects on the fly because if you usednew ClassKey<EnumSet<Shape>> to put an EnumSet into member and then tried to use new ClassKey<EnumSet<Shape>> to retrieve the EnumSet, you would find it would't work because the keys would not be equal. There is no way to write an equals() method for ClassKey that works because, due to type erasure, it would be impossible to tell a ClassKey<EnumSet<Shape>> from a ClassKey<EnumSet<Category>>.
Related
Consider the following invalid Java code:
class Example {
private static class Base {}
private static class Child extends Base{
public void do(){}
}
public void foo(List<Base>) {}
public static void main(String[] args) {
List<Child> list = new ArrayList<>();
fillListInPlaceWithChildren(list);
foo(list); //compile error, List<Child> does not extend List<Base>
list.stream().forEach(Child::do);
}
}
This does not compile because List<Child> is not a subclass of List<Base> and thus cannot be passed to the foo function. To solve this kind of problems I have, as far as I know, 2 options:
let foo accept List<? extends Base>:
class Example {
private static class Base {}
private static class Child extends Base{
public void do(){}
}
public void foo(List<? extends Base>) {}
public static void main(String[] args) {
List<Child> list = new ArrayList<>();
fillListInPlaceWithChildren(list);
foo(list);
list.stream().forEach(Child::do);
}
}
let list be a List<Base> and cast elements to instances of Child when needed
class Example {
private static class Base {}
private static class Child extends Base{
public void do(){}
}
public void foo(List<Base>) {}
public static void main(String[] args) {
List<Base> list = new ArrayList<>();
fillListInPlaceWithChildren(list);
foo(list);
list.stream().forEach((item) -> ((Child)item).do());
}
}
Which option is considered best practice and why? Or do they both have different use cases?
You can't pass List<Child> to a method requiring a List<Base> because it may cause some problems. What would happen in this case if you pass in a List<Child>?
void foo(List<Base> list) {
list.add(new Base());
}
If you do not rely in the list holding only instances of Base. Using List<? extends Base> is safer than adding typecasts in your code, also it causes less surprises to who is reading the code.
I always recomend to use higher level of abstraction. If you can use List<Base> list instead of List<Child> list, use it!.
But in this case is foo whom set its contract. Should foo accept all list inhered from List<? extend Base> or it only make sense to accept List<Child> ?
In the question is the answer.
I come from a C# world and I've just learned about erasure in Java, which put me a bit off. Is there really no way to distinguish SomeGenericInstance<String> from SomeGenericInstance<Integer> runtime in Java?
I'm asking because I've implemented a super simple pub-sub framework and I wanted to have a generic class GenericMessage<T>. It's essential not to send GenericMessage<String> to listeners of GenericMessage<Integer>. I tried implementing it by having a List of key-value pairs where the key is the Class object representing the type of the message. But this code line yields true which is a problem...:
new GenericMessage<Integer>().getClass.equals(new GenericMessage<String>().getClass())
As far as I am aware, sorry, it is simply impossible.
You can do it using Java Reflection. Don't know if it's always a good idea, but it's surely possible. Here's an example:
public class Test{
private List<String> list;
public static void main(String[] args) throws Exception{
Field field = Test.class.getDeclaredField("list");
Field f = field.getGenericType().getClass().getDeclaredField("actualTypeArguments");
f.setAccessible(true);
Type[] genericTypes = (Type[]) f.get(field.getGenericType());
System.out.println(genericTypes[0]);
}
}
Or you can cast directly to ParameterizedType, if it seems any better to you:
public class Test{
private List<String> list;
public static void main(String[] args) throws Exception{
Field field = Test.class.getDeclaredField("list");
ParameterizedType parameterizedType = (ParameterizedType) field.getGenericType();
Type[] actualTypes = parameterizedType.getActualTypeArguments();
System.out.println(actualTypes[0]);
}
}
Both examples print: class java.lang.String
Now just to leave a more complete answer, the same can be done for a Map. As you can see the getActualTypeArguments() method returns a Type[] and for a Map, the key type would be index 0, and the value type would be index 1. Example:
public class Test{
private Map<String, Integer> map;
public static void main(String[] args) throws Exception{
Field mapField = Test.class.getDeclaredField("map");
ParameterizedType mapParameterizedType = (ParameterizedType) mapField.getGenericType();
Type[] actualMapTypes = mapParameterizedType.getActualTypeArguments();
System.out.println(actualMapTypes[0]);
System.out.println(actualMapTypes[1]);
}
}
Prints:
class java.lang.String
class java.lang.Integer
You can access it using next trick:
public class Example<T> {
Class<T> genericType;
public Example(Class<T> genericType) {
this.genericType= genericType;
}
public static void main(String args[]) {
Example<Integer> ex1 = new Example<>(Integer.class);
Example<String> ex2 = new Example<>(String.class);
System.out.println(ex1.genericType);
System.out.println(ex2.genericType);
}
}
Output:
class java.lang.Integer
class java.lang.String
Here's a way of getting what you're looking for without using reflection (assuming that you are able to make modifications to your pub-sub framework to pass a Class token). A big hat-tip to assylias and zvzdhk for pointing me in the direction of class literals.
interface GenericMessage<T> {
}
interface StringMessage<T extends String> extends GenericMessage<T> {
String getString();
}
interface IntMessage<T extends Integer> extends GenericMessage<T> {
int getInt();
}
interface MessageListener<T> {
<T> void handleMessage(Class<T> type, GenericMessage<T> instance);
}
// "marker interfaces"
interface StringMessageListener<T extends String> extends MessageListener<T> {
}
interface IntMessageListener<T extends Integer> extends MessageListener<T> {
}
class IntMessageImpl<T extends Integer> implements IntMessage<T> {
public int getInt() {
return 0;
}
}
class StringListenerImpl<T extends String> implements StringMessageListener<T> {
public <T> void handleMessage(Class<T> type, GenericMessage<T> genericMessage) {
StringMessage stringMessage = (StringMessage) genericMessage; // Typesafe cast since T extends String on both StringMessage and StringMessageListener
String message = stringMessage.getString();
// Do something with message
}
}
class IntListenerImpl<T extends Integer> implements IntMessageListener<T> {
// an implementation for the Integer case ...
}
void showTypeChecking() {
GenericMessage<String> badStringMessage = new IntMessageImpl<>(); // Compile-time check fails due to bad type of new message implementation
MessageListener<Integer> badIntListener = new StringListenerImpl<>(); // Compile-time check fails due to bad type on new listener implementation
MessageListener<String> stringListener1 = new StringListenerImpl<>();
MessageListener<String> stringListener2 = new StringListenerImpl<>();
MessageListener<Integer> intListener = new IntListenerImpl<>();
GenericMessage<String> stringMessage = new GenericMessage<String>() {};
stringListener1.handleMessage(String.class, stringMessage);
stringListener1.handleMessage(Integer.class, stringMessage); // Compile-time check fails due to bad type on class literal
GenericMessage<Integer> intMessage = new GenericMessage<Integer>() {};
intListener.handleMessage(Integer.class, intMessage);
GenericMessage<String> badIntMessage = new GenericMessage<String>() {};
intListener.handleMessage(Integer.class, badIntMessage); // Compile-time check fails due to bad type on intMessage
GenericMessage uncheckedMessage = new IntMessageImpl();
intListener.handleMessage(Integer.class, uncheckedMessage); // Compiler issues warning about unchecked assignment of uncheckedMessage argument
MessageListener uncheckedListener = new StringListenerImpl();
uncheckedListener.handleMessage(String.class, stringMessage); // Compiler issues warning about an unchecked call to handleMessage() method
}
It's not directly applicable in this case, but you may find this discussion of the typesafe heterogeneous container pattern helpful in learning a bit more about Java generics. It's definitely one of the harder parts of the language to master.
It is not possible to distinguish "a SomeGenericInstance<String> object" and "a SomeGenericInstance<String> object", because there is no difference. There is just "a SomeGenericInstance object".
The problem: I've a Function Object interface defined in a class:
public static interface FunctionObject<T> {
void process(T object);
}
I need it generic because I'd like to use T methods in the process implementations.
Then, in other generic class, I've a Map where I have classes as keys and function objects as values:
Map<Class<T>, FunctionObject<T>> map;
But I also want the map to accept subtype classes and function objects of supertypes OF THE KEY TYPE, so I did this:
Map<Class<? extends T>, FunctionObject<? super T>> map; //not what I need
The basic idea is to be able to use the map as follows:
//if T were Number, this should be legal
map.put(Class<Integer>, new FunctionObject<Integer>(){...});
map.put(Class<Float>, new FunctionObject<Number>(){...});
map.put(Class<Double>, new FunctionObject<Object>(){...});
As I want to enforce the FunctionObject has the type of the class key or a supertype, what I really would like to define is this:
Map<Class<E extends T>, FunctionObject<? super E>>> map;
How can I achieve the desired effect? Is a typesafe heterogenous container the only option? What would the Map generic types look like to allow populating it from a reference?
Parametrized container, seems to work just fine:
public class MyMap<T>
{
interface FunctionObject<X> {}
private Map<Class<? extends T>, FunctionObject<Object>> map = new HashMap<>();
#SuppressWarnings("unchecked")
public <E extends T> void put(Class<E> c, FunctionObject<? super E> f)
{
map.put(c, (FunctionObject<Object>) f);
}
public <E extends T> FunctionObject<Object> get(Class<E> c)
{
return map.get(c);
}
public static void Main(String[] args)
{
MyMap<Number> map = new MyMap<>();
map.put(Integer.class, new FunctionObject<Integer>() {});
map.put(Float.class, new FunctionObject<Number>() {});
map.put(Double.class, new FunctionObject<Object>() {});
}
}
Edited to comply to the question. Sadly there is no way to avoid the downcasting to object.
Edit added get().
You can do this with encapsulation, assuming you only use the map through the method which check this on a per entry basis.
The following add method avoids the need to double up on the type as well.
public class Main {
interface FunctionObject<T> { }
private final Map<Class, FunctionObject> map = new LinkedHashMap<Class, FunctionObject>();
public <T> void add(FunctionObject<T> functionObject) {
Class<T> tClass = null;
for (Type iType : functionObject.getClass().getGenericInterfaces()) {
ParameterizedType pt = (ParameterizedType) iType;
if (!pt.getRawType().equals(FunctionObject.class)) continue;
Type t = pt.getActualTypeArguments()[0];
tClass = (Class<T>) t;
break;
}
map.put(tClass, functionObject);
}
public <T> void put(Class<T> tClass, FunctionObject<T> functionObject) {
map.put(tClass, functionObject);
}
public <T> FunctionObject<T> get(Class<T> tClass) {
return map.get(tClass);
}
public static void main(String... args) throws IOException {
Main m = new Main();
m.add(new FunctionObject<Integer>() {
});
FunctionObject<Integer> foi = m.get(Integer.class);
System.out.println(foi.getClass().getGenericInterfaces()[0]);
}
}
prints
Main.Main$FunctionObject<java.lang.Integer>
You can use #SuppressWarnings("unchecked") if you want to disable the warning.
The point is; there is no way to describe the constraint you have in the field declaration, you can achieve the same result if you use accessor methods which do the check on a per entry basis. You can add runtime checks as well if you need to ensure raw types are correct.
I'm trying to write a class that has a generic member variable but is not, itself, generic. Specifically, I want to say that I have an List of values of "some type that implements comparable to itself", so that I can call sort on that list... I hope that makes sense.
The end result of what I'm trying to do is to create a class such that I can create an instance of said class with an array of (any given type) and have it generate a string representation for that list. In the real code, I also pass in the class of the types I'm passing in:
String s = new MyClass(Integer.class, 1,2,3).asString();
assertEquals("1 or 2 or 3", s);
String s = new MyClass(String.class, "c", "b", "a").asString();
assertEquals("\"a\" or \"b\" or \"c\"", s);
Originally I didn't even want to pass in the class, I just wanted to pass in the values and have the code examine the resulting array to pick out the class of the values... but that was giving me troubles too.
The following is the code I have, but I can't come up with the right mojo to put for the variable type.
public class MyClass {
// This doesn't work as T isn't defined
final List<T extends Comparable<? super T>> values;
public <T extends Comparable<? super T>> MyClass (T... values) {
this.values = new ArrayList<T>();
for(T item : values) {
this.values.add(item);
}
}
public <T extends Comparable<? super T>> List<T> getSortedLst() {
Collections.sort(this.values);
return this.values;
}
}
error on variable declaration line:
Syntax error on token "extends", , expected
Any help would be very much appreciated.
Edit: updated code to use List instead of array, because I'm not sure it can be done with arrays.
#Mark: From everything I've read, I really want to say "T is a type that is comparable to itself", not just "T is a type that is comparable". That being said, the following code doesn't work either:
public class MyClass {
// This doesn't work
final List<? extends Comparable> values;
public <T extends Comparable> MyClass (T... values) {
this.values = new ArrayList<T>();
for(T item : values) {
this.values.add(item);
}
}
public <T extends Comparable> List<T> getSortedLst() {
Collections.sort(this.values);
return this.values;
}
}
error on add line:
The method add(capture#2-of ? extends Comparable) in the type List<capture#2-of ? extends Comparable> is not applicable for the arguments (T)
error on sort line:
Type mismatch: cannot convert from List<capture#4-of ? extends Comparable> to List<T>
Conclusion:
What it comes down to, it appears, is that Java can't quite handle what I want to do. The problem is because what I'm trying to say is:
I want a list of items that are
comparable against themselves, and I
create the whole list at once from the
data passed in at creation.
However, Java sees that I have that list and can't nail down that all the information for my situation is available at compile time, since I could try to add things to the list later and, due to type erasure, it can't guarantee that safety. It's not really possible to communicate to Java the conditions involved in my situation without applying the generic type to the class.
I think that the simple answer is that you cannot do that. If the type of one of a classes attributes depends on a type parameter, that parameter has to be declared at the class level. And I don't think that it "makes sense" any other way.
If T in your example is not a type parameter of the class, what is it? It cannot be the type parameter of the method, because that type is determined by how the method is called. (If the method is called in different static contexts with different inferred types for T, what is the notional type of T in the context of the attribute declaration?)
So to bring this back to what you are trying to do here, an instance of MyClass will hold elements of some type, and you want to be able to insert and remove elements in a statically typesafe fashion. But at the same time you don't want to be able to say what that type is. So how is the compiler supposed to statically distinguish between a MyClass instance that holds (say) Integer objects and one that holds String objects?
I don't even think you could implement this with explicit dynamic typechecks. (I think that type erasure means that the implementation of the getSortedList() method cannot find out what actual type is bound to its return type.)
No. The real solution is to make MyClass a generic class that declares the type parameter T; e.g.
public class MyClass <T extends Comparable<T>> {
and remove the declaration of the method-level type parameter T from the two methods.
There's plenty of unchecked warnings in this, but in principle it's not necessary to keep the List as anything but something containing things you know are Comparable. You enforce the rules you need to in the constructor, and everything else should be fine. How about something like this:
public class MyClass {
final private List<Comparable> values;
public <T extends Comparable<? super T>>MyClass(T... values){
this.values = new ArrayList<Comparable>();
for(T item : values) {
this.values.add(item);
}
}
public <T extends Comparable<? super T>> List<T> getSortedLst() {
Collections.sort(this.values);
return (List<T>)this.values;
}
}
A quick test using the following shows that for classes that implement Comparable (like Integer and String) MyClass behaves as expected, but will throw a compilation error for classes that do not implement Comparable:
class Junk { }
public static void main(String[] args){
MyClass s = new MyClass(1,2,3);
System.out.println(s.getSortedLst());
MyClass a = new MyClass("c", "a", "b");
System.out.println(a.getSortedLst());
MyClass c = new MyClass(new Junk());
}
I believe the following will achieve what you want (stronger typing of Comparable). This will prevent people adding Comparable objects which are not from your interface to the list and allow multiple implementations.
public class test<T extends ComparableType> {
final List<T> values = new ArrayList<T>();
public test (T... values) {
for(T item : values) {
this.values.add(item);
}
}
public List<T> getSortedLst() {
Collections.sort(this.values);
return Collections.unmodifiableList(this.values);
}
}
public interface ComparableType extends Comparable<ComparableType> {}
public class ConcreteComparableA implements ComparableType {
#Override
public int compareTo(ComparableType o) {
return 0;
}
}
public class ConcreteComparableB implements ComparableType {
#Override
public int compareTo(ComparableType o) {
return 0;
}
}
edit:
I know this may be obvious; but if you do not wish the class to be Generic this solution will also work with:
public class test {
final List<ComparableType> values = new ArrayList<ComparableType>();
public test (ComparableType... values) {
for(ComparableType item : values) {
this.values.add(item);
}
}
public List<ComparableType> getSortedLst() {
Collections.sort(this.values);
return Collections.unmodifiableList(this.values);
}
}
Consider it like this (what I am about to say isn't reality. but it illustrates why you need to do what you need to do):
class Foo<T>
{
private T value;
T getValue() { return value; }
void setValue(T val) {value = val; }
}
// some code that uses the above class
Foo<Integer> iFoo = new Foo<Integer>();
Foo<String> sFoo = new Foo<String>();
iFoo.setValue(5);
sFoo.setValue("Hello");
When this happens the compiler (DOES NOT REALLY DO WHAT I AM ABOUT TO SAY!) generates the following code:
class IntegerFoo
{
private Integer value;
Integer getValue() { return value; }
void setValue(Integer val) {value = val; }
}
class StringFoo
{
private String value;
String getValue() { return value; }
void setValue(String val) {value = val; }
}
// some code that uses the above class
IntegerFoo iFoo = new IntegerFoo();
StringFoo< sFoo = new StringFoo();
iFoo.setValue(5);
sFoo.setValue("Hello");
If you were able to have the instance variables/methods parameterized without parameterizing the class the above thing (WHICH IS NOT REALITY!) wouldn't work.
What you are trying to do should be possible with static methods, but I don't think that is what you want.
Can you explain why you want to do the code you are trying to do? Perhaps we can figure out a better way to do what you want to do that works within the language.
I'd do it this way (I did it as a list or as an array), unless you really need the instance variable/methods:
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MyClass
{
public static <T extends Comparable<T>> List<T> asSortedList(final T ... vals)
{
final List<T> temp;
temp = new ArrayList<T>(vals.length);
temp.addAll(Arrays.asList(vals));
Collections.sort(temp);
return (Collections.unmodifiableList(temp));
}
public static <T extends Comparable<T>> T[] asSortedArray(final Class<?> clazz,
final T ... vals)
{
final T[] temp;
temp = (T[])Array.newInstance(clazz,
vals.length);
System.arraycopy(vals,
0,
temp,
0,
vals.length);
Arrays.sort(temp);
return (temp);
}
public static void main(final String[] argv)
{
final List<String> list;
final String[] array;
list = MyClass2.asSortedList("c", "a", "b");
System.out.println(list);
array = MyClass2.asSortedArray(String.class, "z", "y", "x");
System.out.println(Arrays.deepToString(array));
}
}
the type constraint you want on the variable can't be expressed directly. you can introduce a new type to bridge the problem.
static class MyList<T extends Comparable<? super T>> extends ArrayList<T>{}
final MyList<?> values;
however, there is no point to be extremely type safe in a private piece of code. Generic is there to help you clarify your types, not to obfuscate them.
public class MyClass<T extends Comparable<? super T>> {
// This doesn't work as T isn't defined
final List<T> values;
public MyClass (T... values) {
this.values = new ArrayList<T>(Arrays.asList(values));
}
public List<T> getSortedLst() {
Collections.sort(this.values);
return this.values;
}
}
Is it possible to tie nested generics/captures together?
I often have the problem of having a Map lookup of class to genericized item of said class. In concrete 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/get to have semantics something like these:
<T> ServiceLoader<T> get(Class<T> klass) {...}
<T> void put(Class<T> klass, ServiceLoader<T> loader) {...}
Is the following the best I can do? Do I have to live with the inevitable #SuppressWarnings("unchecked") somewhere down the line?
private Map<Class<?>, ServiceLoader<?>> loaders = Maps.newHashMap();
Let me see If I got your intention: you want a map that stores pairs of Class/ServiceLoader where each pair is parameterized by the same T, but T may be different across pairs?
If this is the case then the best solution is to declare your own class which will exhibit such an interface. Internally it will store these pairs in a generic Map<Class<?>,ServiceLoader<?>> map.
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") annotations are not pure evil. You should try to avoid them but there are certain cases where you can figure out that the cast is correct despite the fact that the compiler cannot see that.
My suggestion is to create a new Object for such case. I see you were using Maps.newHashMap() so I take it that you used Google Guava so I will use ForwardingMap.
public class Loader<T> extends ForwardingMap<Class<T>, ServiceLoader<T>> {
private Map<Class<T>, ServiceLoader<T>> delegate = Maps.newHashMap();
}
A simple test proved that my suggestion is working:
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);
}
}