Generics multiple types

Method definition as

myMethod(Object... obj){} 

allows you to use an arbitrary number and types of parameters.

I would like to use generics to strictly define the number and types of parameters.

For example, suppose the aforementioned myMethod(Object...) is a method in a class called MyClass and MyClass , which can be created by default by the constructor.

I need to define instances in a way similar to this:

 MyClass<Integer, Integer, String> instance1 = new MyClass<Integer, Integer, String>(); MyClass<String, String, Integer, Integer> instance2 = new MyClass<String, String, Integer, Integer>(); 

therefore, the above type definitions specify the number and types of parameters allowed when calling myMethod() :

 instance1.myMethod(1, 2, "test"); instance2.myMethod("one", "two", 1, 2); 

The question arises: how to define MyClass in such a way as to allow any number of type parameters?

Any advice would be appreciated.

+4
source share
6 answers

I do not think that what you are trying to do can be achieved, but perhaps you could give some idea of ​​what myMethod() does?

+3
source

You cannot, the number of type parameters is fixed for each class. you can play crazy tricks

 class Tuple { Object[] objects() { return ...; } } class Tuple1 ... class Tuple2 ... class Tuple3<T1,T2,T3> extends Tuple { static public<S1,S2,S3> Tuple3<S1,S2,S3> of(S1 o1, S2 o2, S3 o3){ return ...; } } class Tuple4<T1,T2,T3,T4> extends Tuple { static public<S1,S2,S3,S4> Tuple4<S1,S2,S3,S4> of(S1 o1, S2 o2, S3 o3, S4 o4){ return ... ; } } ... class Tuple9 ... class MyClass<TupleN extends Tuple> { void myMethod(TupleN ntuple) { Object[] objects = ntuple.objects(); // work on objects } } MyClass<Tuple3<Integer,Integer,String>> instance3 = new MyClass<Tuple3<Integer, Integer, String>>(); instance3.myMethod( Tuple3.of(1,2,"test") ); 

It is not worth it . Sometimes you need to give up extraneous type checking for simplicity.

+3
source

What's the point? I can not imagine a scenario where this would be useful, and be the best solution. I am not trying to humiliate, but it is worth mentioning that you must subscribe to the KISS principle . It sounds like you are becoming a victim of over-engineering, and it smells like code.

An alternative design pattern that can be useful is the Builder pattern . The wiki page examples are not so good, but you should read the Effective Java section on collectors. The constructor will help to create an immutable object constructed using the necessary and / or optional parameters by combining the mutator methods and calling the private constructor using the construction method:

 public class MyClass { private final String string1; private final String string2; private final int int1; private final int int2; private MyClass(Builder builder) { this.string1 = builder.string1; this.string2 = builder.string2; this.int1 = builder.int1; this.int2 = builder.int2; } public String getString1() { return string1; } public String getString2() { return string2; } public int getInt1() { return int1; } public int getInt2() { return int2; } public static class Builder { private String string1; private String string2; private int int1; private int int2; // set required parameters in the constructor public Builder() { } public Builder string1(String string1) { this.string1 = string1; return this; } public Builder string2(String string2) { this.string2 = string2; return this; } public Builder int1(int int1) { this.int1 = int1; return this; } public Builder int2(int int2) { this.int2 = int2; return this; } public MyClass build() { return new MyClass(this); } } } 

You would create an object like this:

 MyClass myClass = new MyClass.Builder().string1("sample1").string2("sample2").int1(1).int2(2).build(); 

Or (using the same class)

 MyClass myClass = new MyClass.Builder().string1("sample1").int1(1).build(); 

These are terrible method names, but I'm moving away from your hypothetical scenario.

+3
source
+3
source

You can try the following:

Class Type: MyClass <List<?>>

0
source

You should be content with myMethod(Object...) . MyClass instances are not even aware of parameter types at runtime.

0
source

All Articles