user986139
user986139

Reputation:

How to get constructor of a class with a generic parameter in the constructor

The problem: To get parameterized constructor reference of subclasses of A (such as class H shown below) in class C.

Class A<T extends B> {
  public A(T objectT, D objectD, E objectE, F objectF) {

  }

  public T aMethodWithTAsReturnType();
}

Class B { }

Class C<T extends A<?>> {
  private Constructor<?> classAConstructor;
  public C(Class<T> classA) {
     classAConstructor=classA.getConstructor(B.class, D.class,E.class,F.class)
  }
}

Class H extends A<X> {
  public H(X objectX, D objectD, E objectE, F objectF) {}
}

Class X extends B {}

new C(new H(objectX,objectD,objectE,objectF));

The above code configuration would result in a NoSuchMethodException when a new Class C object is created because it cannot find the constructor for Class A

I am now trying to use:

Method methodInA = classA.getMethod('aMethodWithTAsReturnType')
Class<?> TClassInA = methodInA.getReturnType();

as a replacement for B.class in the classA.getConstructor line as I'm guessing that's the issue here because class B is a super type of T (in Class A).

However... when I used methodInA.getReturnType() it returns B.class! rather than a class that has extended B. I then found a getGenericReturnType() method but it returns a Type object.

Upvotes: 2

Views: 2321

Answers (2)

munyengm
munyengm

Reputation: 15479

This works for me:

public class G {
    static class A<T extends B> {
        A(T objectT, D objectD, E objectE, F objectF) { }
    }

    static class B { }

    static class C<XT extends B, T extends A<XT>> {
        private Constructor<?> classAConstructor;
        public C(Class<T> classA, Class<XT> classX) throws SecurityException, 
            NoSuchMethodException {
            classAConstructor = classA.getConstructor(classX, D.class,
                    E.class, F.class);
        }
    }
    static class D { }
    static class E { }
    static class F { }

    static class X extends B { }

    public static class H extends A<X> {
        public H(X objectT, D objectD, E objectE, F objectF) {
            super(objectT, objectD, objectE, objectF);
        }
    }

    public static void main(String[] args) throws SecurityException,
        NoSuchMethodException {
        new C<X, H>(H.class, X.class);
    }
}

UPDATE: You will need to find some way of passing the parameterisation of A into C. I've updated your code to illustrate one way of doing so.

Upvotes: 1

JB Nizet
JB Nizet

Reputation: 691765

getConstructor() returns only public constructors. Try with getDeclaredConstructor().

EDIT:

The problem is that the H constructor doesn't take a B as argument, but a X (which is a subclass of B). The signature of the constructor is thus H(X, D, E, F). This constructor only accepts instances of X as its first argument. It doesn't accept any kind of B instances, but only instances of X.

Upvotes: 0

Related Questions