Java optional parameters
如何在Java中使用可选参数?什么规范支持可选参数?
有几种方法来simulate可选参数:在Java
方法的重载。
1 2 3 4 5 6 7 8 9 10 |
这一方法的局限性是,它不工作,如果你有一个双T型参数和可选的任何他们可以omitted。
varargs。
所有的参数都是可选的)相同的类型:
1 2 3 4 5 6 7 8 |
(b)可选的参数可能是不同的类型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | 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"); |
这种方法的主要缺点是,如果不同类型的可选参数都是静态类型检查,你输了。此外,如果每个参数的意义,你需要有一些不同的方式来distinguish他们。
nulls。地址在以前的方法的局限性,你可以允许的,然后分析每个参数的值:在方法体
1 2 3 4 5 6 7 |
现在,所有的参数值必须被设置,默认的,但可能是空的。。。。。。。。
可选的类。该方法是使用类似于nulls Java类,但这已经是8可选参数的默认值。
1 2 3 4 5 6 7 |
可选的方法是使合同显者,然而,一个可以找到这样的签名太冗长。
更新:Java的类
生成器模式。建造模式是用于实现的构造器是由单独的工具类:介绍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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(); |
谷歌地图。当参数的数量太大和是最通常使用的默认值,你可以通过自己的方法参数的名称/值的地图。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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")); |
在Java的方法9,这对更容易:
1 2 3 4 5 6 7 8 9 10 11 12 13 | @SuppressWarnings("unchecked") static <T> T getParm(Map<String, Object> map, String key, T defaultValue) { return (map.containsKey(key)) ? (T) map.get(key) : defaultValue; } void foo(Map<String, Object> parameters) { String a = getParm(parameters,"a",""); int b = getParm(parameters,"b", 0); // d = ... } foo(Map.of("a","a", "b",2, "d","value")); |
请注意,你可以结合任何这些方法desirable实现结果。
这是可能的varargs(的方式)。这是比其他所有变量的声明,必须提供的方法。如果你想变的过载是可选的,你可以使用签名的方法,这是不是要求的参数。
1 2 3 4 5 6 7 8 9 | private boolean defaultOptionalFlagValue = true; public void doSomething(boolean optionalFlag) { ... } public void doSomething() { doSomething(defaultOptionalFlagValue); } |
你可以使用的东西,像这样:
在
奇怪,我找不到任何关于这个的文件,但它的作品!
这是一个"新"在1.5和超越(不支持Java在Java 1.4或早期)。
我看到了下面这bhoot提到的用户。
有一个用Java 5.0的可选参数。你只是把像这样的函数:
1 2 3 4 | public void doSomething(boolean... optionalFlag) { //default to"false" //boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false; } |
你可以用电话或
不幸的是,Java不支持默认参数的T头。
然而,我写的annotations集和一个JavaBean,他们支持默认参数如下列:
1 2 3 4 5 6 7 8 9 10 11 | 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); } |
该处理器生成的注释的方法来支持这overloads恰当。
国有企业code.google.com http:/ / / / / / annotations P javadude维基
例如,在全code.google.com http:/ / / / / P javadude annotationsdefaultparametersexample维基
在Java中有可选参数。你可以是一个函数的重载和默认值来传递的。
1 2 3 4 5 6 7 8 | void SomeMethod(int age, String name) { // } // Overload void SomeMethod(int age) { SomeMethod(age,"John Doe"); } |
varargs和超载已被提到。另一个选项是一个会看的东西Builder模式,像这样:
1 2 3 4 | MyObject my = new MyObjectBuilder().setParam1(value) .setParam3(otherValue) .setParam6(thirdValue) .build(); |
虽然这一模式将是最合适的选择是当你需要在构造函数的参数。
的JDK 1.5中>你可以使用它,像这样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | 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); } } } |
它将取决于你想要实现的在线varargs方法重载,或解决方案,应报。一些好的例子在这里:如何使用它们
blog.sleekface.com http:/ / / / / Java方法中的核心和可选的参数/
但在心,不在继续使用方法重载。它带来了混乱。
短版:
使用三个点:
1 2 3 4 5 6 |
(基于@vitalifedorenko的答案)
您可以使用这样的方法重载来完成这项工作。
也可以使用@nullable注释
1 |
只需将空值作为第一个参数传递。
如果传递的是同一类型变量,则可以使用
1 |
重载是可以的,但是如果有很多变量需要默认值,那么最终会得到:
1 2 3 4 5 6 7 | 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) { } |
所以我建议使用Java提供的变量参数。这里有一个解释链接。
Java现在支持OpTales在1.8,我在Android上停留在编程上,所以我使用Null直到我可以重构代码来使用可选类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
您可以使用类似于生成器的类来包含这样的可选值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public class Options { private String someString ="default value"; private int someInt= 0; public Options setSomeString(String someString) { this.someString = someString; return this; } public Options setSomeInt(int someInt) { this.someInt = someInt; return this; } } public static void foo(Consumer<Options> consumer) { Options options = new Options(); consumer.accept(options); System.out.println("someString =" + options.someString +", someInt =" + options.someInt); } |
类使用
1 | foo(o -> o.setSomeString("something").setSomeInt(5)); |
输出是
1 | someString = something, someInt = 5 |
要跳过所有的可选值,您必须像
使用这种方法,您可以按任意顺序指定可选值,而不会产生任何歧义。与varargs不同,您还可以拥有不同类的参数。如果可以使用注释和代码生成来创建选项类,这种方法会更好。
在Java中不能使用默认参数。在C++、C++和Python中,我们可以使用它们。
在Java中,我们必须使用2个方法(函数),而不是使用默认参数的方法。
例子:
1 2 3 | 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-
我们可以通过方法重载或使用数据类型来设置可选参数…
|*|方法重载:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
最简单的方法是
|*|数据类型…可以是可选参数
1 2 3 4 5 6 7 | RetDtaTyp NamFnc(int NamPsgVar, String... SrgOpnPsgVar) { if(SrgOpnPsgVar.length == 0) SrgOpnPsgVar = DefSrgVar; // |* CodTdo *| return RetVar; } |