Using Generics to Construct Instances of Child Classes

jipthechip :

While looking at some Java 8 code I saw some use of generics that I didn't quite understand, so I wrote my own code to emulate what was going on:

public class GenericsTest {

    public static void main(String[] args) {
        TestBuilder tb = TestBuilder.create(Test_Child::new);
        Product<Test_Child> p = tb.build();

        Test tc = p.Construct("Test");
    }

    static class TestBuilder<T extends Test> {

        private final Factory<T> f;

        public TestBuilder(Factory<T> f) {
            this.f = f;
        }

        public static <T extends Test> TestBuilder<T> create(Factory<T> f){
            return new TestBuilder<>(f);
        }

        public Product<T> build(){
            return new Product<>(f);
        }

    }

    static class Test {
        public Test(){
        }
    }

    static class Test_Child extends Test{
        public Test_Child(String s){
            System.out.println("Test_Child constructed with string '"+s+"'");
        }
    }

    interface Factory<T extends Test> {
        T create(String s);
    }


    static class Product<T extends Test>{
        private Factory<T> f;

        public Product(Factory<T> f) {
            this.f = f;
        }

        public T Construct(String s){
            return f.create(s);
        }
    }
}

Running this prints:

Test_Child constructed with string 'Test'

What I don't understand is:

  1. Why don't you have to provide arguments to Test_Child::new
  2. How calling f.create() in the Product instance refers to the constructor of the Test_Child class.
Andronicus :
  1. The method awaits Factory<T> as the input parameter:

    public static <T extends Test> TestBuilder<T> create(Factory<T> f)
    

    And Factory is an interface with only one method:

    interface Factory<T extends Test> {
        T create(String s);
    }
    

    That makes it effectively a functional interface, that can be implemented by simply passing a lambda: Function<String, T> (a function that creates an instance of type T from String). Test_Child::new is such a lambda, because it consumes String and produces T.

  2. As stated Factory is a function, that takes a String and creates T. By calling the method create, we're invoking the function.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=360006&siteId=1