1

Say I have a method that takes 2 parameters

public Class Test{
        public void Foo(int x, SOMETHING HERE(Optional and unknown at runtime)){

        }
}

And in my main

public Class Main{
    public static void main(String[]args){
    Test test = new Test();
    String s1 = "Hello";
    float f1 = 5.5f;

    test.Foo(10);
    test.Foo(10, s1);
    test.Foo(10, f1);
    test.Foo(10, s1, f1);
    test.Foo(10, f1, s1);
    }
}

How can I achieve what I want without creating several methods?

  • 1
    Seems to me like you have to overload the method `Foo` (which by convention should probably be called `foo`). – Tom O. Oct 11 '17 at 20:37
  • @TommyO It's in an interface. So I don't want to make many copies within an interface. –  Oct 11 '17 at 20:40
  • 1
    `Test` is an interface? It's marked as a `Class` in your code above. – Tom O. Oct 11 '17 at 20:50
  • my actual implementation is an interface (same idea, just made it a class to make it easier)....i got my answer below thanks –  Oct 11 '17 at 20:58

2 Answers2

0

When the number of arguments after the first int argument is not defined & they might have different types, you can use varargs method signature

public Class Test{
   public void Foo(int x, Object... args) {

   }
}

The only problem with this approach is that you need to handle arguments carefully inside your Foo method

For ex. to iterate arguments you can use loop and check the type instance:

for (Object item : args) {
   if (item instanceof String) {
      // do stuff
   }
}

The other way is to get arguments length & get theirs particular values one by one:

final int maxArgs = args.length;
if (maxArgs > 0) {
    final Object arg0 = args[0];
    if (arg0 instanceof String) {
        final String strArg0 = (String) arg0;
        //do stuff
    }
}

Basically it depends on your demands

Alex Saunin
  • 976
  • 1
  • 8
  • 15
  • ok in the method implementation, how can i access the args? does it become an array of objects (so if i put a string followed by a float, the args[0] would be the string and args[1] would be the float?) –  Oct 11 '17 at 20:45
0

I cannot comment yet, so I will provide a preliminar answer with the information you gave so far, but I think it needs clarification.

As people already stated this question seems to relate to java optional parameters (especially: varargs of Object). Considering your example (main()) I also would go for a serie of overloaded methods but it considerably depends on the number of different optional arguments you expect to come with and any conflict of arguments ordering that may occur.

Other alternatives include defining an interface for your argument "SOMETHING_HERE" that could be filled in any possible mean at runtime (and also used anonymously). So among others (like using a map for variable typed args), you could eventually do as follow:

Eg.

public interface IDynLoadedArgs { public Float getFloat(); // returns NULLABLE public String getString(); // returns NULLABLE }

public Class Test{
    public void foo(int x, IDynLoadedArgs args){
        ...
    }
}

public Class Main{
    public static void main(String[]args){
        Test test = new Test();
        final String s1 = "Hello";
        final float f1 = 5.5f;

        test.foo(10, null); // = might equal test.foo(10);
        test.foo(10, new IDynLoadedArgs() {
            public Float getFloat(){
                return null;
            }
            public String getString(){
                return s1;
            }
        });    // = might equal test.foo(10, s1);
        test.foo(10, new IDynLoadedArgs() {
            public Float getFloat(){
                return f1;
            }
            public String getString(){
                return null;
            }
        });    // = might equal test.foo(10, f1);
        test.foo(10, new IDynLoadedArgs() {
            public Float getFloat(){
                return f1;
            }
            public String getString(){
                return s1;
            }
        });    // = might equal test.foo(10, f1, s1);
        ...
    }
}

Of course you may instantiate IDynLoadedArgs objects in the classic way before calling "foo" (hence avoiding anonymous things side-effects and making these objects reusable..

Nevertheless as soon as you don't precise in your original question that order matters and what kind of treatment you expect of method "foo", it is hard to propose something definitely appropriate. Please clarify if possible.

bsaverino
  • 1,221
  • 9
  • 14