Home > Enterprise >  Can you get constructor function from an unknown class?
Can you get constructor function from an unknown class?

Time:12-09

Hey so I recently discovered this new thing in java, it allows you to reference static methods or constructors as a function. If a constructor looks like this

public MyClass(String str){
    System.out.println(str);
}

You would be able to do something like this MyClass::new and it would then return java.util.function.Function<String, MyClass>. I was wondering if there was a way to get this function from the Class object of the class. So like

Class<?> class = MyClass.class;
// VVV Like this
Function<String, MyClass> func = class::new;

or is it not possible. If you know how or if it even is possible, please let me know. Any help is appreciated.

CodePudding user response:

Using reflection, an instance of Constructor<MyClass> may be retrieved, but it is not convertible to Function<String, MyClass> directly.

But there method Constructor::newInstance but it throws several checked exceptions. Therefore, a special functional interface supporting checked exceptions needs to be used instead of plain Function:

@FunctionalInterface
public interface FunctionWithExceptions<T, R, E extends Exception> {
    R apply(T t) throws E;
}

Then the reference to the constructor's newInstance method may be created and used:

public class MyClass {
    public MyClass(String str) {
        System.out.println(str);
    }

    public static void main(String[] args) throws ReflectiveOperationException {
        Function<String, MyClass> cons = MyClass::new;
        System.out.println(cons);
        cons.apply("Test lambda");

        Constructor<MyClass> constructor = MyClass.class.getDeclaredConstructor(String.class);

        System.out.println(constructor);
        constructor.newInstance("Test constructor");

        FunctionWithExceptions<String, MyClass, ReflectiveOperationException> funCons = constructor::newInstance;
        System.out.println(funCons);
        funCons.apply("Test reference to constructor newInstance");

    }
}

Output:

MyClass$$Lambda$14/0x0000000800066840@67b92f0a
Test lambda
public MyClass(java.lang.String)
Test constructor
MyClass$$Lambda$15/0x0000000800066c40@61f8bee4
Test reference to constructor newInstance
  • Related