Java Reflection getConstructor method
Asked Answered
P

3

9

Lets say I have classes A and B, where B extends A. I also have a constructor in B with one argument which is of type A. I also have an object of type B called bObj.

Is there a way to call B.class.getConstructor(new Class[] { bObj.getClass() }) and get the constructor since B extends A? At the moment I'm getting a NoSuchMethodException.

Plutonium answered 22/11, 2012 at 8:42 Comment(3)
What about using B.class.getConstructors(), find the ones that take exactly one argument, and check whether A.class isAssignableFrom this one?Autry
arne.b This is one way of doing it but I thought it could actually be easier. Nandkumar Yes, it is public.Plutonium
Thank you for the advice. I think I'm satisfied with what you provided as an answer. :)Plutonium
J
10

I suggest you have a look at the ConstructorUtils from Apache Commons Lang.
They have all manners of constructor discovery methods.

Your case should be covered by "Matching Accessible Constructors".

Here is an example of the method used in context. Basically, you call it like this:

 private <T> T instantiate(Class<?> input, Object parameter) {
  try {
    Constructor<?> constructor = ConstructorUtils.getMatchingAccessibleConstructor(input, parameter.getClass());
    return (T) constructor.newInstance(parameter);
  } catch (Exception e) {
    //handle various exceptions
  } 
}
Joinery answered 22/11, 2012 at 8:53 Comment(1)
This works flawlessly and is - in my opinion - quite elegant. Two additional hints: (1) If you declare the "input" parameter as Class<T> input, you can prevent casting the return value. (2) ConstructorUtils.invokeConstructor(Class<T> cls, Object... args) combines getting the constructor and creating a new instance.Rist
T
4

No, the methods which search for you expect exact parameters. So when you look for a constructor, method or field using find/search methods of the reflection API, the API uses equals() to find matches.

If you need the same logic that the Java compiler would use, you will need to use a framework like FEST Reflect or commons beanutils. Or you must call getConstructors() and write your own filter code.

At first glance, this seems stupid: If the Java compiler can do it, why can't the Reflection API? There are two reasons: First, the Java runtime doesn't need to search which method to call because the compiler already selected the correct method.

The second reason is that the Reflection API was always "second best". It can do everything but the goal was never to make it really easy/friendly to use (at least, that's what I think every time I use it :-)

Terza answered 22/11, 2012 at 8:51 Comment(0)
F
0

if your constructor is not public (or if it's class is not public), or not accessible from your code scope, it will not be returned through

Class.getConstructor()

try

Class.getDeclaredConstructor()

instead

Fairfield answered 13/12, 2016 at 12:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.