2

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.

4
  • Please provide a set of compilable classes, because in my tests, everything runs fine (I have left out E and F, made all classes public, added the necessary throws clauses, and tested by executing C c = new C(A.class);. Everything runs fine. Commented Jul 6, 2012 at 11:24
  • Updated the code to include all the related classes. E and F can be left as they're irrelevant base classes such as Integer and Boolean. Commented Jul 6, 2012 at 11:49
  • Your code doesn't even compile. Don't expect it to run. See @munyengm's answer for compilable code (that also runs fine). That said, H doesn't have a constructor with a B as first argument. It has one with a X as first argument. Commented Jul 6, 2012 at 11:52
  • That is correct. And X is a subclass of B. Commented Jul 6, 2012 at 12:14

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Updated the code. H has a constructor that has an objectX. So in your example, class H extends A<X>
This looks like the only way to do it. Passing the class explicitly.
0

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.

1 Comment

It is a public constructor, sorry my psuedo code initially missed it out.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.