In Java, can you specify any number of typical type parameters?

I am looking to create a specific type of interface in Java (although this also applies to regular classes). This interface should contain some method, for example invoke ; it will be called with a different number of parameters depending on the provided arguments of the generic type.

As an example:

 public interface Foo<T...> { public void invoke(T... args); } // In some other class public static Foo<Float, String, Integer> bar = new Foo<Float, String, Integer>() { @Override public void invoke(Float arg1, String arg2, Integer arg3) { // Do whatever } }; 

To briefly explain how this can be used (and provide some context), consider the Delegator class: the class accepts a different number of common types and has one method - invoke , with these parameters types. The method passes its parameters to the object in the list: an instance of IDelegate , which takes the same generic types. This allows the Delegator to choose between several delegate methods (defined inside an IDelegate ) without the need to create a new class for each specific list of parameter types.

Is there anything similar? I read about variadic templates in C ++, but can't find anything like it in Java. Is there such a thing? If not, what will be the cleanest way to emulate the same data model?

+8
java generics
source share
3 answers

Is there anything similar? I read about variable templates in C ++, but cannot find anything like it in Java. Is there such a thing available?

No, this feature is not available in Java.

+4
source share

No, there is nothing of the kind directly available. However, if you use a library with Tuple classes, you can mimic it by simply creating an interface

 interface Foo<T> { void invoke(T t); } 

(This interface is essentially the same as Consumer<T> .)

Then you could do, for example,

 Foo<Tuple<String, Integer, Date, Long>> foo = new Foo<>() { ... } 

For each number of parameters, a separate Tuple type is required. If you have a Tuple class for 4 parameters, but not one for 5, you can compress an additional parameter using the Pair class.

 Foo<Tuple<String, Integer, Date, Pair<Long, BigDecimal>>> foo = ... 

When nesting tuple types this way, you get an unlimited number of parameters. However, these workarounds are really ugly, and I would not use them.

+2
source share

Given the context you provided, I recommend using the List parameter as a parameter. If these options have something in common, you can keep your list to <T extends CommonParrent> instead of using List<Object> . If not, you can still use the marker interface.

Here is an example.

 public class Main { public static void main(String[] args) { delegate(asList(new ChildOne(1), new ChildTwo(5), new ChildOne(15))); } private static <T extends Parent> void delegate(List<T> list) { list.forEach(item -> { switch (item.type) { case ONE: delegateOne((ChildOne) item); break; case TWO: delegateTwo((ChildTwo) item); break; default: throw new UnsupportedOperationException("Type not supported: " + item.type); } }); } private static void delegateOne(ChildOne childOne) { System.out.println("child one: x=" + childOne.x); } private static void delegateTwo(ChildTwo childTwo) { System.out.println("child two: abc=" + childTwo.abc); } } public class Parent { public final Type type; public Parent(Type type) { this.type = type; } } public enum Type { ONE, TWO } public class ChildOne extends Parent { public final int x; public ChildOne(int x) { super(Type.ONE); this.x = x; } } public class ChildTwo extends Parent { public final int abc; public ChildTwo(int abc) { super(Type.TWO); this.abc = abc; } } 

The biggest drawback of this solution is that children must specify their type through enum, which must correspond to the casts in the switch statement, so whenever you change one of these two places, you will need to remember the other, because the compiler will not tell you about it. You can find such an error by running the code and executing a specific branch, therefore it is recommended to develop a test development.

+2
source share

All Articles