Wildcard class as variable in constructor

Viewed 693

I have class A

class A{}

class A1 extends class A

class A1 extends A{}

now in class B, I want to pass any class that extends class A as a variable.

class B{
    Class<? extends A> variable;

    public B(Class<? extends A> variable) {
        this.variable = variable;
    }
}

to run above, the driver class is as below

 class C {
    public static void main(String args[]) {
        B b=new B(new A());// A cannot be converted to Class<? extends A>.
        B b=new B(new A1());// A1 cannot be converted to Class<? extends A>.
            }
}

because Class<? extends A> variable it means, any class extending class A can be passed in the constructor and A1 is extending A, then why its giving error?

what am I missing?

3 Answers

I suspect that what you're actually trying to do is to set up B so it can work with instances of A or any subtype of A. To do that, you'll need to make the class B itself generic:

class B<T extends A> {
    T variable;

    public B(T variable) {
        this.variable = variable;
    }
}

class C {
    public static void main(String args[]) {
        B<A> b = new B<>(new A());
        B<A1> b1 = new B<>(new A1());
    }
}

Class<? extends A> variable means that variable can hold a reference to an object of type Class, not to something that extends A.

Class is a "meta-class", its purpose is to describe another class. From a Class instance you can get all the fields and all the methods that this class provides. You can take a look to the Java reflection tutorial for more informations.

To make your code work you can write something like this:

class B<T extends A> {
    private T variable;
    public B(T variable) {
        this.variable = variable;
    }
}

class C {
    public static void main(String args[]) {
        B<A> b = new B<>(new A());
        B<A1> b1 = new B<>(new A1());
    }
}

In this way you're creating a generic class B which accepts instances of A or something that extends A

What would work instead is:

B b = new B(A.class); // class type expected and not the instance of

or

B b = new B(A1.class);

To explain further, parameter Class<? extends A> variable means that <? extends A> is the type of the class modeled by the supplied Class object. Hence you need to supply either class A or any class extending A as an argument but of type Class.

Related