Java可选参数

如何在Java中使用可选参数? 什么规范支持可选参数?

可变参数可以做到这一点(在某种程度上)。 除此之外,必须提供方法声明中的所有variables。 如果你想要一个variables是可选的,你可以使用一个不需要参数的签名来重载方法。

 private boolean defaultOptionalFlagValue = true; public void doSomething(boolean optionalFlag) { ... } public void doSomething() { doSomething(defaultOptionalFlagValue); } 

有几种方法来模拟Java中的可选参数:

  1. 方法重载。

     void foo(String a, Integer b) { //... } void foo(String a) { foo(a, 0); // here, 0 is a default value for b } foo("a", 2); foo("a"); 

    这种方法的局限之一是,如果你有两个相同types的可选参数,它们不起作用,任何参数都可以省略。

  2. 可变参数。

    a)所有可选参数都是相同的types:

     void foo(String a, Integer... b) { Integer b1 = b.length > 0 ? b[0] : 0; Integer b2 = b.length > 1 ? b[1] : 0; //... } foo("a"); foo("a", 1, 2); 

    b)可选参数的types可能不同:

     void foo(String a, Object... b) { Integer b1 = 0; String b2 = ""; if (b.length > 0) { if (!(b[0] instanceof Integer)) { throw new IllegalArgumentException("..."); } b1 = (Integer)b[0]; } if (b.length > 1) { if (!(b[1] instanceof String)) { throw new IllegalArgumentException("..."); } b2 = (String)b[1]; //... } //... } foo("a"); foo("a", 1); foo("a", 1, "b2"); 

    这种方法的主要缺点是,如果可选参数是不同的types,你会失去静态types检查。 而且,如果每个参数有不同的含义,你需要一些方法来区分它们。

  3. 空值。 为了解决以前方法的限制,可以允许空值,然后分析方法体中的每个参数:

     void foo(String a, Integer b, Integer c) { b = b != null ? b : 0; c = c != null ? c : 0; //... } foo("a", null, 2); 

    现在所有的参数值都必须提供,但默认值可能为空。

  4. 可选课程 这种方法类似于空值,但对于具有默认值的参数使用Java 8可选类:

     void foo(String a, Optional<Integer> bOpt) { Integer b = bOpt.isPresent() ? bOpt.get() : 0; //... } foo("a", Optional.of(2)); foo("a", Optional.<Integer>absent()); 

    可选方法为调用者明确地创build一个方法合同,但是,可能会发现这样的签名过于冗长。

    更新:Java 8包含了类java.util.Optional开箱即用,所以在java 8中没有必要使用guava这个特殊的原因。方法名称虽然有点不同。

  5. build造者模式。 构build器模式用于构造函数,并通过引入一个单独的Builder类来实现:

      class Foo { private final String a; private final Integer b; Foo(String a, Integer b) { this.a = a; this.b = b; } //... } class FooBuilder { private String a = ""; private Integer b = 0; FooBuilder setA(String a) { this.a = a; return this; } FooBuilder setB(Integer b) { this.b = b; return this; } Foo build() { return new Foo(a, b); } } Foo foo = new FooBuilder().setA("a").build(); 
  6. 地图。 当参数数量太大,并且通常使用大多数默认值时,可以将方法参数作为名称/值的映射:

     void foo(Map<String, Object> parameters) { String a = ""; Integer b = 0; if (parameters.containsKey("a")) { if (!(parameters.get("a") instanceof Integer)) { throw new IllegalArgumentException("..."); } a = (Integer)parameters.get("a"); } if (parameters.containsKey("b")) { //... } //... } foo(ImmutableMap.<String, Object>of( "a", "a", "b", 2, "d", "value")); 

请注意,您可以结合使用这些方法来获得理想的结果。

你可以使用这样的东西:

 public void addError(String path, String key, Object... params) { } 

paramsvariables是可选的。 它被视为对象的可空数组。

奇怪的是,我在文档中找不到任何关于这个的东西,但它起作用了!

这是Java 1.5及更高版本中的“新”(Java 1.4或更早版本不支持)。

我看到用户bhoot在下面提到了这一点。

Java 5.0有可选的参数。 只要声明你的function是这样的:

 public void doSomething(boolean... optionalFlag) { //default to "false" //boolean flag = (optionalFlag.length >= 1) ? optionalFlag : false; } 

你可以调用doSomething();doSomething(true); 现在。

不幸的是,Java不直接支持默认参数。

不过,我写了一组JavaBean注释,其中一个支持如下的默认参数:

 protected void process( Processor processor, String item, @Default("Processor.Size.LARGE") Size size, @Default("red") String color, @Default("1") int quantity) { processor.process(item, size, color, quantity); } public void report(@Default("Hello") String message) { System.out.println("Message: " + message); } 

注释处理器生成方法重载以正确支持这一点。

请参阅http://code.google.com/p/javadude/wiki/Annotations

http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample上的完整示例;

Java中没有可选参数。 你可以做的是重载函数,然后传递默认值。

 void SomeMethod(int age, String name) { // } // Overload void SomeMethod(int age) { SomeMethod(age, "John Doe"); } 

已经提到了VarArgs和重载。 另一种select是Builder模式,它看起来像这样:

  MyObject my = new MyObjectBuilder().setParam1(value) .setParam3(otherValue) .setParam6(thirdValue) .build(); 

尽pipe这种模式对于在构造函数中需要可选参数的时候是最合适的。

在JDK> 1.5中,你可以像这样使用它;

 public class NewClass1 { public static void main(String[] args) { try { someMethod(18); // Age : 18 someMethod(18, "John Doe"); // Age & Name : 18 & John Doe } catch (Exception e) { e.printStackTrace(); } } static void someMethod(int age, String... names) { if (names.length > 0) { if (names[0] != null) { System.out.println("Age & Name : " + age + " & " + names[0]); } } else { System.out.println("Age : " + age); } } } 

这取决于你想实现什么,可变参数或方法重载应该可以解决大多数场景。

但请记住不要过度使用方法重载。 它带来了混乱。

你可以用这样的方法重载。

  public void load(String name){ } public void load(String name,int age){} 

你也可以使用@Nullable注解

 public void load(@Nullable String name,int age){} 

只需传递null作为第一个参数。

如果你正在传递相同types的variables,你可以使用这个

 public void load(String name...){} 

重载是好的,但是如果有很多需要默认值的variables,你将会得到:

 public void methodA(A arg1) { } public void methodA( B arg2,) { } public void methodA(C arg3) { } public void methodA(A arg1, B arg2) { } public void methodA(A arg1, C arg3) { } public void methodA( B arg2, C arg3) { } public void methodA(A arg1, B arg2, C arg3) { } 

所以我会build议使用Java提供的variables参数。 这里有一个解释的链接 。

默认参数不能用在Java和C#中。 在C ++和Python中,我们可以使用它们..

在Java中,我们必须使用2个方法(函数),而不是使用默认参数。

例:

Stash(int size);

Stash(int size,int initQuantity);

http://parvindersingh.webs.com/apps/forums/topics/show/8856498-java-how-to-set-default-parameters-values-like-c-

Java现在支持1.8中的可选项,我坚持在android编程,所以我使用空值,直到我可以重构代码使用可选types。

 Object canBeNull() { if (blah) { return new Object(); } else { return null; } } Object optionalObject = canBeNull(); if (optionalObject != null) { // new object returned } else { // no new object returned } 

简短版本:

(基于@ VitaliiFedorenko的回答)

 public void foo(Object... x) { String first = x.length > 0 ? (String)x[0] : "Hello"; int duration = x.length > 1 ? Integer.parseInt((String) x[1]) : 888; } foo("Hii", ); foo("Hii", 146); 

我们可以通过方法重载或使用DataType使可选参数…

| * | 方法重载:

 RetDtaTyp NamFnc(String NamPsgVar) { // |* CodTdo *| return RetVar; } RetDtaTyp NamFnc(String NamPsgVar) { // |* CodTdo *| return RetVar; } RetDtaTyp NamFnc(int NamPsgVar1, String NamPsgVar2) { // |* CodTdo *| return RetVar; } 

最简单的方法是

| * | DataType …可以是可选参数

 RetDtaTyp NamFnc(int NamPsgVar, String... SrgOpnPsgVar) { if(SrgOpnPsgVar.length == 0) SrgOpnPsgVar = DefSrgVar; // |* CodTdo *| return RetVar; }