Passing Child.class as argument [duplicate] - java

This question already has answers here:
Is List<Dog> a subclass of List<Animal>? Why are Java generics not implicitly polymorphic?
(19 answers)
Closed 5 years ago.
I have a method that should receives a Class<A>, something like:
protected void method(final Class<A> clazz) {
}
Then when I try to call like method(A.class) it do works, but if I try method(B.class), where B is child of A, I get the message "incompatible types".
The solution is change to Class<B>, but I have another childs that I like to pass as argument to this method(), like C.class.

One solution would be to use a bounded wildcard when defining the parameter:
protected void method(final Class<? extends A> clazz) {
// Code here...
}
With this, you are allowed to pass A's class directly or any class that extends from A.
Or as Pavlo suggested:
protected <T extends A> void method(final Class<T> clazz) {
// Code here...
}
Both will work, but it would help to know what you plan to do with clazz so we can select one over the other.

Related

Generics in java at method level [duplicate]

This question already has answers here:
Why does this Java method appear to have two return types?
(3 answers)
Closed 6 months ago.
I am new to java. I am trying to debug a code and not able to understand one line.
public interface CommandDispatcher {
<T extends BaseCommand> void registerHandler(Class<T> type, CommandHandlerMethod<T> handler);
void send(BaseCommand command);
}
I know generics but not able to understand below line.
<T extends BaseCommand> void registerHandler(Class<T> type, CommandHandlerMethod<T>)
what is <T extends BaseCommand> before void also I am not ablr to understand Class<T>
Can somebody explain me to understand the above line. Consider BaseCommand is an interface.
<T extends BaseCommand> means at the calling side Type T can be BaseCommand OR derived from BaseCommand class/interface.
Class<T> type means the first argument should be the type of Class T.
class Command extends BaseCommand{
}
then you can call like this
registerHandle( Command.class, ...);
So that inside implementation one can create instance of Type Command.

Class Generics method definition [duplicate]

This question already has answers here:
How do I make the method return type generic?
(19 answers)
Closed 5 years ago.
Assuming that you have a lot of classes that extends the class Base.
class Base{}
class A extends Base[}
class B extends Base{}
class C extends Base{}
What must I write so that when I write a get method, I will get the class that I want?
public Base get(Class <? extends Base> clazz, final String key){
//not important.
}
I want the method to return Objects of class A, B, or C, depending on the input clazz.
public <T extends Base> T get(Class<T> clazz, final String key) {
}
is closer to what you need. Keep in mind that during method declared generic variables, to have more success you typically put the modifiers outside of the parameter list.

Is it possible to make generic method signature implementing generic + interface? [duplicate]

This question already has answers here:
Why can't I use a type argument in a type parameter with multiple bounds?
(5 answers)
Closed 7 years ago.
Is it possible to use generics something like that in Java 1.7?
class Test<T> {
public <Z extends T & Serializable> void method(Z test) {
...
}
}
I would like my method to accept only objects of generic type which implements specific interface.
No, unfortunately it is not possible to use generic extends with a generic type and an interface. In fact, it is not even possible to use generic extends with multiple types. If you could, then you could do something like the following.
class Test<T, B extends Serializable> {
public <Z extends T & B> void method(Z test) {
...
}
}
This restriction against extending multiple types may be because of type erasure. At runtime the generics are removed and public <Z extends Serializable> simply becomes public Serializable. So what would <Z extends T & Serializable> be replaced with?
The most approximated form would be:
class Test<T extends Serializable>
{
public <Z extends T> void method(Z test)
{
}
}

Instantiate a Generic Type [duplicate]

This question already has answers here:
Instantiating a generic class in Java [duplicate]
(10 answers)
Closed 9 years ago.
My code is:
public class MyClass<T extends MyComponent> {
private T t;
public MyClass(){
t = new T();
}
}
But the compiler don't accept new T(). Is there a way to do this using the constructor MyClass(), without parameters?
You could do
public class MyClass<T extends MyComponent> {
private T t;
MyClass(Class<T> clazz) throws InstantiationException,
IllegalAccessException {
t = clazz.newInstance();
}
}
Because of type erasure, the JVM doesn't know what T is, so it can't instantiate it. The workaround is to provide a Class<T> and use it to create a new instance:
public MyClass(Class<T> clazz)
{
t = clazz.newInstance();
}
You'll have to add catching IllegalAccessException and InstantiationException.
Not without access to T's class object. Think about it, T could be any subclass of MyComponent, how would you even decide which constructors are available on that particular subclass?
Type erasure means that the compiler silently replaces all "real" references to T with MyComponent.
If you have a reference to Class, you may call Class#newInstance, or get a constructor and invoke that.

Java generic method declaration [duplicate]

This question already has answers here:
What is the difference between bounded wildcard and type parameters?
(2 answers)
Closed 10 years ago.
I'm learning Java generics and I ask myself this question.
What is the difference between these two method declarations?
public static void someMethod(List<? extends Number> numberList);
and
public static <E extends Number> void someMethod(List<E> numberList);
In the latter you have a reference to the type within the scope of someMethod, namely E. In the former you do not.
The main difference is that the latter is a generic method the former is not.
So for example in the latter method you can do something like this:
public static <E extends MyObject> void someMethod(List<E> someList) {
E myObject = someList.iterator().next(); // this can actually lead to errors
myObject.doSomething(); // so treat it as an example
}
This means that you can substitute an arbitrary type E which conforms to the rule in the generic method declaration and be able to use that type in your method.
Be advised though that you should call the generic method with type arguments like this:
someClass.<MyArbitraryType>someMethod(someList);
You can find a nice overview of generic methods here.
With the second version you can do something like:
public static <E extends Number> void someMethod(List<E> numberList) {
E number = numberList.get(0);
numberList.add(number);
}
This isn't possible with the first version.
Using the first method declaration will not allow you to add anything new to the list. For example this will not compile.
public static void someMethod(List<? extends Number> numberList, Number number) {
numberList.add(number);
}
while the second allows you to do this:
public static <T extends Number> void someMethod(List<T> numberList, T number) {
numberList.add(number);
}

Categories

Resources