How to implement a method with an unknown number of arguments?

Viewed 6159

I have 1 interface and 3 class. I would like the class to be able to both implement the interface which need a transform method. This method must exist but there can't be more than one per class. I don't know the number of parameters taken by this class.

Example :

public interface A{
    public void transform(Object ... args);
}

public class B implements A{
    public void transform(String a){
        System.out.println(a);
    }
}

public class C implements A{
    public void transform(Integer a, Character b){
        System.out.println(a+b);
    }
}

// super generic case if possible with Objects + primitive
public class D implements A{
    public void transform(int a, String b){
        System.out.println(a+b);
    }
}

This doesn't work. But I hope you got the idea. Is something like this possible in java ? How should I call them in a generic way ? Let's say if I have an other method like :

void callTransf(A a, Object ... objs){
    Method m = a.getClass().getMethods()[0];
    m.invoke(a, objs)
}
7 Answers

It's a very old question but I don't see a correct implementation in any of the solution. OP was going the right way and is the correct implementation but needs to be written like this -

public interface A<T>{
    public T transform(Object ... args);
}

public class B implements A{
    public void transform(Object ... args){
        System.out.println((String)args[0]);
    }
}

public class C implements A{
    public void transform(Object ... args){
        Integer a = (Integer)args[0];
        Integer b = (Integer)args[1];
        System.out.println(a+b);
    }
}


 public static void main(String [] vals){
 //Interface A
 A b = new B();
 A c = new C();
 b.transform("Hello");
 c.transform(new Integer(1), 'c');

}    

You will see it's importance if you use Spring or other DI framework then all you need to do is

@Inject
@Qualifier("B") // For Implementation class B
A b;


@Inject
@Qualifier("C") // For Implementation class C
A C

I see accepted answer is very convuluted and in the end, it is just directly calling the implementation class -
Ex:TransformerB b = new TransformerB;
b.transform();
What's the point of creating all the interfaces???

One possible solution could be to use Marker Interfaces. A marker (or tagging) interface is an interface that has no methods or constants inside it. It provides run-time type information about objects.

Here is an example that uses Input interface as transform method parameter. An instance of a class that implements this marker interface can be used as transform method argument.

public interface Input {
}
public interface Transformable {
  void transform(Input input);
}
public class InputForA implements Input {
  int a;
  String b;

  public int getA() {
    return a;
  }

  public InputForA setA(int a) {
    this.a = a;
    return this;
  }

  public String getB() {
    return b;
  }

  public InputForA setB(String b) {
    this.b = b;
    return this;
  }
}
public class TransformerA implements Transformable {
  @Override
  public void transform(Input input) {
    InputForA inputForA = (InputForA) input;
    System.out.println(inputForA.getA() + inputForA.getB());
  }
}
Related