Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics - Class or Class<? extends SomeClass>

I am writing a program which will use Java reflection (i.e., Class.forName()) to dynamically create class instance based on user's input. One requirement is that the instance my program creates must extend one specific Class I defined, called it SomeClass. My question is: for storing this class type, should I use bounded generic, Class<? extends SomeClass>, or simply unbounded generic, Class? I found some Java books say that Class is one of the good practices for using unbounded wildcard generic, but I am wondering whether this apply to the situation in my program.

Please feel free to let me know if you found my question is not clear enough or some information is needed.

like image 466
keelar Avatar asked Jun 06 '13 18:06

keelar


People also ask

What does <? Extends mean in Java?

The extends keyword extends a class (indicates that a class is inherited from another class). In Java, it is possible to inherit attributes and methods from one class to another. We group the "inheritance concept" into two categories: subclass (child) - the class that inherits from another class.

Can you extend a generic class?

Generic class can also extend another generic class. When generic class extends another generic class, sub class should have at least same type and same number of type parameters and at most can have any number and any type of parameters.

What is difference between extends and super in generics?

extends Number> represents a list of Number or its sub-types such as Integer and Double. Lower Bounded Wildcards: List<? super Integer> represents a list of Integer or its super-types Number and Object.

What <> means Java?

What Does Java Mean? Java is an object-oriented programming language that produces software for multiple platforms.


1 Answers

You should use Class<? extends SomeClass> because that's what generics are for.

At the time when you invoke Class.forName, check to see if it SomeClass.class.isAssignableFrom the new class. Otherwise, you should throw an IllegalArgumentException or ClassCastException.

EDIT: Alternatively, calling asSubclass(SomeClass.class) will do this for you.

For example:

public SomeClass instantiate(String name)
  throws ClassNotFoundException, InstantiationException, IllegalAccessException {

    Class<?> raw = Class.forName(name);

    //throws ClassCastException if wrong
    Class<? extends SomeClass> generic = raw.asSubclass(SomeClass.class);

    // do what you want with `generic`

    return generic.newInstance();
}
like image 100
wchargin Avatar answered Oct 01 '22 04:10

wchargin