Assuming code like below:
public interface Component<T>
{
}
public class ConcreteComponent<T> implements Component<T>
{
}
How would you solve such compilation problem:
#Override
public Class<? extends Component<?>> getComponentClass() {
// Does not compile!
return ConcreteComponent.class;
}
Basically, as you can see I'd like to able to construct object via reflection using component's class. Ommiting the details, method's declaration might look like this:
public <T extends Component<?>> void createComponent(Class<? extends T> clazz)
{
}
And finally:
ConcreteComponent<Integer> cmp = createComponent(getComponentClass());
Any help would be appreciated!
This compiles:
public Class<? extends Component> getComponent() {
// Compiles!
return ConcreteComponent.class;
}
Return (Class>) ConcreteComponent.class;
You can use either of the below code.
The return type you have mentioned should match the value you have returned so you need to cast it to the return type.
public class ConcreteComponent<T> implements Component<T> {
public Class<? extends Component<?>> getComponent() { // Does not compile!
return (Class<? extends Component<?>>) ConcreteComponent.class;
}
}
OR
public class ConcreteComponent<T> implements Component<T> {
public Class<? extends Component<?>> getComponent() {
return (Class<? extends Component<?>>) this.getClass();
}
}
Related
Assuming we have a method like this:
public void foo(Class<? extends ClassBar> x) {
...
}
By modifying the generic expression;
< ? extends ClassBar >
Is it possible to ensure that ClassBar.class can't be passed in but anything extends ClassBar directly or indirectly be passed in WITHOUT throwing an exception on the runtime?
If you have only a bunch of classes extending ClassBar you can follow these two approaches.
Solution 1:
have all subclasses of ClassBar extend a custom interface (except for ClassBar itself), and change the method signature to:
public <T extends ClassBar & MyInterface> void foo(Class<T> x) {
...
}
Solution 2:
use something similar to this #AndyTurner's trick and provide instances only for specific types.
E.g:
class ClassBar {}
class ClassBarA extends ClassBar{}
class ClassBarB extends ClassBar{}
Your class containing foo:
class Foo<T extends ClassBar> {
private Foo() {} // private constructor
public static <T extends ClassBarA> Foo<T> instance(T c) {
return new Foo<T>();
}
public static <T extends ClassBarB> Foo<T> instance(T c) {
return new Foo<T>();
}
public void foo(Class<T> c) {
}
}
Only subclass of ClassBarA would be accepted in this case
Foo<ClassBarA> foo1 = Foo.instance(this.classBarA);
foo1.foo(ClassBarA.class); // pass
foo1.foo(ClassBar.class); // fail
I have an interface:
public interface Displayable {
public Class <Screen> classToDisplay();
}
and some classes:
public class Screen {
}
public class ScreenSubclass extends Screen {
}
public class Cue implements Displayable {
#Override displayClass() {
return ScreenSubclass.class;
}
}
I'm getting an IDE error telling me they are incompatible types. What return value would be needed for 'classToDisplay()' to return a class or subclass type of Screen?
Just figured it out. Use the ? wildcard along with 'extends'...
Change the return type for 'displayClass' to:
public Class<? extends Screen> displayClass();
Problem:
I have two interfaces (here GenCarry and Gen):
public interface GenCarry<T extends Gen> {
GenCarry<T> setGen(T gen);
}
public interface Gen<T extends GenCarry> {
void applyOn(T carry);
}
It works when I ignore the 'rawtypes' Warning, but trying to complete them I don't get too far:
GenCarry<T extends Gen<GenCarry<T>>>
Gen<C extends GenCarry<Gen<C>>> -> error: not a valid substitute for the bounded parameter.
Question:
How would an interface like that look if complete - or is that even possible?
Is there a better approach to "generalize" an interface like that?
You can define two type parameters:
public interface GenCarry<K extends GenCarry<K, T>, T extends Gen<T, K>> {
GenCarry<K, T> setGen(T gen);
}
public interface Gen<K extends Gen<K, T>, T extends GenCarry<T, K>> {
void applyOn(T carry);
}
class StringGenCarry implements GenCarry<StringGenCarry, StringGen> {
#Override
public StringGenCarry setGen(StringGen client) {
...
}
}
class StringGen implements Gen<StringGen, StringGenCarry> {
#Override
public void applyOn(StringGenCarry network) {
...
}
}
I have a class:
public class MultipleSorting<T extends Enum<?>> {
private T criteriaType;
public Class<T> getCriteriaClass() {
Field field = ReflectionUtils.getField(getClass(),"criteriaType");
ReflectionUtils.makeAccessible(field);
return (Class<T>)field.getType();
}
}
This class is get instantiated as:
public abstract class MultiSortPageableController<T extends MultiSortPageableController<?,?>, U extends Enum<?>> {
private MultipleSorting<U> multipleSorting;
public MultiSortPageableController() {
super();
multipleSorting = new MultipleSorting<U>();
}
}
The actual value of U is passed from the child class of MultiSortPageableController which is:
public abstract class AbstractArticleSearchController<T extends AbstractArticleSearchController<T>> extends MultiSortPageableController<T,ArticleSortField> {
}
The ArticleSortField is an Enum.
I was expecting the method getCriteriaClass of MultipleSorting would return ArticleSortField from a method of MultiSortPageableController. But it is returning java.lang.Enum.
I am unable to figure it out why it is not returning the actual enum and how can I make it so. Any pointer would be very helpful to me. I need to get ArticleSortField.
Purpose:
I two requirement:
To get the actual class of enum type (say ArticleSortField.class)
To list enum value. If I have the enum class, then I could invoke class..getEnumConstants().
Java compiler removes information about generics, therefore when you use reflection you get no information about the declared type, other than Enum. This process is called type erasure.
How about passing the type down, via the constructor, like this:
public class MultipleSorting<T extends Enum<?>> {
private Class<T> criteriaType;
MultipleSorting(Class<T> criteriaType) {
this.criteriaType = criteriaType;
}
public Class<T> getCriteriaClass() {
return criteriaType;
}
}
public abstract class MultiSortPageableController<T extends MultiSortPageableController<?, ?>, U extends Enum<?>> {
private MultipleSorting<U> multipleSorting;
public MultiSortPageableController(Class<U> criteriaType) {
super();
multipleSorting = new MultipleSorting<U>(criteriaType);
}
}
public abstract class AbstractArticleSearchController<T extends AbstractArticleSearchController<T>> extends MultiSortPageableController<T, ArticleSortField> {
public AbstractArticleSearchController() {
super(ArticleSortField.class);
}
}
I'm trying to create a generic service that is based on a class with a generics based collection
public class GenericClass<T> {
List<T> results;
public List<T> getResults() {
return results;
}
}
Im just not sure how to create a service that is based on this GenericClass and has a concrete implementation of T. I would expect something like
public class ServiceManagerImpl<GenericClass<T>> implements ServiceManager<GenericClass<T>> {
public GenericClass<T> getMyClass() {
...
}
}
But the compiler doesn't like this. Any ideas how to do this?
Marc
You are close... just pass the T through:
public class ServiceManagerImpl<T> implements ServiceManager<GenericClass<T>> {
public GenericClass<T> getMyClass() {
...
}
}
I can suggest the following implementation that doesn't break the rules of JLS:
// ServiceManager.java
public interface ServiceManager<E, T extends GenericClass<E>> {
}
// ServiceManagerImpl.java
public class ServiceManagerImpl<E, T extends GenericClass<E>> implements ServiceManager<E, T> {
public T getMyClass() {
return null;
}
}
The content between <> is called Type Parameters, and GenericClass<T> is not a valid Type Parameter in declaration.
Quote from java generic guide
A generic class is defined with the following format:
class name<T1, T2, ..., Tn> { /* ... */ }
The type parameter section, delimited by angle brackets (<>), follows the class name. It specifies the type parameters (also called type variables) T1, T2, ..., and Tn.
so, you need to use GenericClass<T> in implementation, not in declaration.
// declaration
public class ServiceManagerImpl<YourGenericType> implements ServiceManager<YourGenericType> {
public YourGenericType getMyClass() {
...
}
}
// implementation
ServiceManager<GenericClass<Object>> sm = new ServiceManagerImpl<GenericClass<Object>>();
public class ServiceManagerImpl<T extends GenericClass<T>> implements ServiceManager<T extends GenericClass<T>> {
public GenericClass<T> getMyClass() {
...
}
}
I am not sure my answer is legal , but it seems meet your requirement:
public class ServiceManagerImpl<T extends GenericClass> implements ServiceManager<T>
{
#Override
public T getMyclass() {
//do your work here;
}
}
Although it may have a unchecked warning when I declare this class , but this really does!
ServiceManager<GenericClass<Integer>> manager = new ServiceManagerImpl<GenericClass<Integer>>();//passed
You should try likes this;
public class ServiceManagerImpl<GenericClass<Object>> implements ServiceManager<GenericClass<Object>> {
public GenericClass<Object> getMyClass() {
...
}
}
You can replace Object with Integer or String or any data types as you likes.