在运行时传递可选的未知参数

passing optional unknown parameters at runtime

假设我有一个接受 2 个参数的方法

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

        }
}

而在我的主要

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);
    }
}

如何在不创建多个方法的情况下实现我想要的?

当第一个 int 参数之后的参数数量未定义且它们可能具有不同的类型时,您可以使用 varargs 方法签名

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

   }
}

这种方法的唯一问题是您需要在 Foo 方法

中小心处理参数

例如。要迭代参数,您可以使用循环并检查类型实例:

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

另一种方法是获取参数长度并逐一获取它们的特定值:

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

基本上看你的需求

我还不能评论,所以我会根据你目前提供的信息提供一个初步的答案,但我认为这需要澄清。

正如人们已经指出的那样,这个问题似乎与 java 可选参数(尤其是:对象的可变参数)有关。考虑到您的示例 (main()),我也会选择一系列重载方法,但这在很大程度上取决于您期望附带的不同可选参数的数量以及可能发生的参数顺序冲突。

其他替代方案包括为您的参数 "SOMETHING_HERE" 定义一个接口,它可以在运行时以任何可能的方式填充(也可以匿名使用)。因此,除其他外(例如对变量类型的参数使用映射),您最终可以执行以下操作:

例如。

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);
        ...
    }
}

当然,您可以在调用 "foo" 之前以经典方式实例化 IDynLoadedArgs 对象(从而避免匿名事物的副作用并使这些对象可重用..

然而,一旦您在最初的问题中没有明确说明顺序很重要以及您希望对方法进行什么样的处理 "foo",就很难提出绝对合适的建议。如有可能请说明。