Quantcast
Viewing latest article 36
Browse Latest Browse All 49

Answer by blacktide for Adding a Java element that's a subclass of a list, within a method with generic parameter

If generic enums were possible in Java, then this would be a simple solution, but unfortunately that is not possible. Here is an option that may suit your needs.

Create a generic interface that contains your newA method:

public interface AType<T extends A> {    T newA(final int a);}

Then create a class that will contain public static instances of this interface, somewhat simulating an enum:

public static class ATypes {    public static AType<A1> A1_TYPE = new AType<A1>() {        @Override        public A1 newA(int a) {            return new A1(a);        }    };    public static AType<A2> A2_TYPE = new AType<A2>() {        @Override        public A2 newA(int a) {            return new A2(a);        }    };}

Thanks to Java 8+ function references, we can simplify this class significantly:

public static class ATypes {    public static AType<A1> A1_TYPE = A1::new;    public static AType<A2> A2_TYPE = A2::new;}

Then, change the syntax of your insertA method to be generic with the bounds of T extends A:

public static <T extends A> void insertA(final AType<T> t,                                         final List<T> al,                                         final int x) {    final T newA = t.newA(x);    al.add(newA);}

Now the following code will work:

public static void main(String[] args) {    final List<A1> list1 = new ArrayList<>();    final List<A2> list2 = new ArrayList<>();    insertA(ATypes.A1_TYPE, list1, 1);    insertA(ATypes.A2_TYPE, list2, 2);    // the following will not compile (types switched)    // insertA(ATypes.A2_TYPE, list1, 1);    // insertA(ATypes.A1_TYPE, list2, 2);}

Alternatively, you could always skip the intermediate type and just pass the function reference directly like so:

public static void main(String[] args) {    final List<A1> list1 = new ArrayList<>();    final List<A2> list2 = new ArrayList<>();    insertA(A1::new, list1, 1);    insertA(A2::new, list2, 2);}public static <T extends A> void insertA(final Function<Integer, T> t,                                         final List<T> al,                                         final int x) {    final T newA = t.apply(x);    al.add(newA);}

Viewing latest article 36
Browse Latest Browse All 49

Trending Articles