如何定义一个可以在java中获取任意参数的方法?

如何定义一个可以在java中获取任意参数的方法? 有演示吗?

varargs在Java 5中引入。

例如:

public String join(String... parts); 

这实际上是一个捷径:

 public String join(String[] parts); 

parts参数在方法中用作数组,但是可以在不构造数组的情况下调用该方法(如obj.join(new String[] {part1, part2, part3})

但是要非常小心,因为可能会产生歧义。 例如:

 public void write(String author, String... words); public void write(String... words); 

如果obj.write("Mike", "jumps")将调用哪个方法? 编译器足够聪明,可以检测到歧义,但是我遇到过某些编译器没有发现这些问题的情况(无法准确回忆)

当对象具有相同类型或至少具有相同的function目标时,使用varargs是实用的。 如果你想要不同的论点。 例如:

 public String publishBook(String title, [String author], [String isbn], [boolean hardcover]); // [..] would mean optional 

那么你需要重载你的方法

可变长度参数列表

它在一般情况下不起作用。 即使您将方法定义为:

  @SafeVarargs public void callMe(Object... args) { ... } 

当你调用callMe(1, "hallo", 3.14159, new Object()) ,这将起作用。 但是,如果要在接口上使用类似的方法,则不能使用@SafeVarargs ,因为它只能添加到最终方法中(以免它们被不安全的实现覆盖)。

在这种情况下,您可以做的最好的事情是在您的界面中定义:

  @SuppressWarnings("unchecked") public  void callMe(T... args); 

当使用相同运行时类型的对象调用callMe时,这至少会省略警告,例如`callMe(“a”,“b”,“c”)。 但是,当您使用不同类型调用时会出现警告,如上例所示:

  ArbitraryCallable x = new ArbitraryCallableImplementation(); x.callMe("a", "b"); // no warning x.callMe(1, "x", 3.14159); // warning 

不要忘记,因为Object...只是Object[]语法糖,你不能简单地调用`callMe(new Object [] {“a”}},因为这会产生一个模糊的情况:你想调用吗? callMe与一个Object(恰好是一个数组)或与数组的元素?

这是一个关于变量参数的简单教程 。 示例代码:

 public void foo (ParamType ... name) { } 

对于传递可变数量的参数,您可以使用varargs语法(您指定一个类型后跟省略号,并且所谓的参数是指定类型的数组,Java将添加一些语法糖,以便您可以通过在任何数量的该类型的列表中,它将自动放入数组中)。

对于传递任意类型,可以使用Javagenerics来允许任意类型,或者可以使用类型Object。 通常使用generics更好,因为你会得到更多的类型检查,但两者都可以。

  • 可变参数
  • generics

这是varargs的一个例子:

 public static void printAll(String ... args){
    for(String str:args){
       的System.out.println(STR);
    }
 }
 //现在可以写printAll(“Hello”,“world”,“etc”,“etc”);

以下是generics的示例:

 public static  void print(T obj){
    的System.out.println(obj.toString());
 }

我担心即使你考虑varargs(因为它们只是一种类型),java还不能开箱即用(与其他一些语言相比)。 但是,OO模式是您的朋友,您可以使用Builder模式来完成您的需求。 一个简短的例子(从Effective Java 2nd Edition中窃取改编和缩短)

  public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; public static class Builder { // Required parameters private final int servingSize; private final int servings; // Optional parameters - initialized to default values private int calories = 0; private int fat = 0; public Builder(int servingSize, int servings) { this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val) { calories = val; return this; } public Builder fat(int val) { fat = val; return this; } public NutritionFacts build() { return new NutritionFacts(this); } } private NutritionFacts(Builder builder) { servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; } } 

有了它,你可以做类似的事情

 NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8). calories(100).fat(35).build(); 

现在真正酷的是,你可以添加实际采用varargs的方法,这使得这个特殊的模式非常强大。 此模式还使您的对象不可变,并使您免于编写telescoping构造函数。 它不会做的是你的菜,但我生活在希望中;)