I really want to do "new T ()"! (And without inspection exceptions)

Conclusion

Receives an instance of a functional interface that creates a T-type instance as an argument.

// newT()Methods that require
<T> T doSomething(Supplier<T> supplier) {
    T instance = supplier.get();
    return instance;
}

//Method to call doSomething
void caller() {
    Test instance = this.doSomething(() -> new Test());
}

Commentary

Sometimes you know that new T () is an anti-pattern in the first place, but you want to do new T (). The following patterns are often presented as solutions at that time.

Get a Class instance and do newInstance ()


<T> T doSomething(Class<T> clazz) throws InstantiationException, IllegalAccessException {
    T instance = clazz.newIntance();
    return instance;
}

void caller() {
   Test instance = this.doSomething(Test.class);
}

The problem with this code is that it throws a checked exception.

Throw a checked exception

Throw ʻInstantiationException and ʻIllegalAccessException as in the code above. I think it's a reasonable design for the Class.newInstance () side, but there are times when the user can be confident that the constructor won't throw an exception ... Then, it is troublesome to bother to try-catch or throws the above exception. Furthermore, since it is a check exception, it is incompatible with stream [^ 1], and try-catch is required internally.

<T extends SuperTest> List<T> doSomething(Class<T> clazz, List<String> valueList) throws InstantiationException, IllegalAccessException {
    return valueList.stream()
        .map(value -> {
            //I want to write smartly with stream, but try-catch…
            try {
                T obj = clazz.newInstance();
                obj.setValue(value);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        })
        .collect(Collectors.toList());
}

In that respect, the functional interface does not generate extra checked exceptions, so it is relatively clean (unless the constructor has throws). [^ 1]: To be exact, it is incompatible with the functional interface.

Digression

If the constructor takes an argument, use an instance of Function <T, R>. If there are two, BiFunction <T, U, R>. If there are 3 or more, create a class for the argument or use java.util.Map.

1 argument


// newT()Methods that require
<T> T doSomething(Function<String, T> func) {
    T instance = func.apply("Constructor arguments");
    return instance;
}

//Method to call doSomething
void caller() {
    Test instance = this.doSomething((str) -> new Test(str));
}

Two arguments


// newT()Methods that require
<T> T doSomething(BiFunction<String, Integer, T> func) {
    T instance = func.apply("Constructor arguments", 1);
    return instance;
}

//Method to call doSomething
void caller() {
    Test instance = this.doSomething((str, number) -> new Test(str, number));
}

Recommended Posts

I really want to do "new T ()"! (And without inspection exceptions)
I want to do team development remotely
[Ruby] I want to do a method jump!
I want to do something like "cls" in Java
I want to transition screens with kotlin and java!
[Swift] I want to do something like C's sprinftf
[Rails] I don't want to get lost anymore. Create new models, tables, controllers and views.
I want to build Java Applet without using an IDE
I want to bring Tomcat to the server and start the application
I want to call a method and count the number
[jackson] I want to receive JSON values "0" and "1" as boolean
I want to implement various functions with kotlin and java!
I want to convert characters ...
I want to give edit and delete permissions only to the poster
Webpack and webpacker I want to tell Ruby people right now
I want to be able to think and write regular expressions myself. ..
I want to return to the previous screen with kotlin and java!
I want to perform asynchronous processing and periodic execution with Rail !!!
I want to use FormObject well
I want to convert InputStream to String
I want to display images with REST Controller of Java and Spring!
[Active Admin] I want to customize the default create and update processing
[Ruby] I want to extract only the value of the hash and only the key
I want to pass the argument of Annotation and the argument of the calling method to aspect
I want to introduce the committee with Rails without getting too dirty