Abstraction of class and generics

I need to extend an abstract class that I cannot change:

public abstract class CustomField<T> extends AbstractField<T> implements HasComponents { // some code @Override public abstract Class<? extends T> getType(); // some code } 

With a common class like this:

 public class VerticalCheckBoxSelect<T> extends CustomField<Set<T>> { @Override public Class<? extends Set<T>> getType() { return ???; } } 

My question is obvious: what should VerticalCheckBoxSelect::getType be returned to compile (and the correct one)?

+5
source share
2 answers

You can return Class.class.cast(HashSet.class);

Which will be compiled, but will give you a warning about an unchecked task.

+3
source

Description

What you are actually doing is somehow equivalent to this,

 public class VerticalCheckBoxSelect<T> extends CustomField<Set> { @Override public Class<? extends Set> getType() { return ???; } } 

Notice that the first line says extends CustomField<Set> , which means that public abstract Class<? extends T> getType() public abstract Class<? extends T> getType() should be implemented in such a way that it will always return a Class<Set> , so your implementation should be:

 public class VerticalCheckBoxSelect<T> extends CustomField<Set<T>> { @Override public Class<? extends Set<T>> getType() { @SuppressWarnings("unchecked") Class<Set<T>> r = (Class) Set.class; return r; } } 

The above code now compiles fine. Give it a try!

Now let's say that you want it to be an arbitrary subclass of Set , like a HashSet , then replace the above Set.class with HashSet.class :

 public class VerticalCheckBoxSelect<T> extends CustomField<Set<T>> { @Override public Class<? extends Set<T>> getType() { @SuppressWarnings("unchecked") Class<Set<T>> r = (Class) HashSet.class; return r; } } 
+1
source

All Articles