【问题标题】:passing optional unknown parameters at runtime [duplicate]在运行时传递可选的未知参数
【发布时间】:2018-03-23 15:36:23
【问题描述】:

假设我有一个需要 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);
    }
}

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

【问题讨论】:

  • 在我看来,您必须重载方法 Foo(按照惯例,它可能应该称为 foo)。
  • @TommyO 它在一个界面中。所以我不想在一个界面中复制很多。
  • Test 是接口吗?在上面的代码中它被标记为Class
  • 我的实际实现是一个接口(同样的想法,只是把它变成了一个类以使其更容易)......我在下面得到了答案,谢谢

标签: java oop optional-parameters


【解决方案1】:

当第一个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
    }
}

基本上取决于你的要求

【讨论】:

  • 在方法实现中确定,我如何访问 args?它会变成一个对象数组吗(所以如果我在一个字符串后面加上一个浮点数,那么 args[0] 将是字符串,而 args[1] 将是浮点数?)
【解决方案2】:

我还不能发表评论,所以我将根据您目前提供的信息提供初步答案,但我认为需要澄清。

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

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

例如。

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”进行什么样的处理,就很难提出绝对合适的建议。如果可能,请澄清。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多