Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java generic parameter as exact subclass?

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?

like image 927
iGoodie Avatar asked Sep 03 '26 07:09

iGoodie


1 Answers

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
like image 74
Marko Pacak Avatar answered Sep 05 '26 21:09

Marko Pacak



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!