Javaでオプションのパラメータを使用する方法どの仕様がオプションのパラメータをサポートしていますか?
可変引数はそれを(ある方法で)行うことができます。それ以外は、メソッドの宣言内のすべての変数を指定する必要があります。変数をオプションにしたい場合は、パラメータを必要としないシグネチャを使用してメソッドをオーバーロードできます。
private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {
...
}
public void doSomething() {
doSomething(defaultOptionalFlagValue);
}
Javaでオプションのパラメータをシミュレートする方法はいくつかあります。
メソッドのオーバーロード
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");
この方法の制限の1つは、同じタイプの2つのオプションのパラメータがあり、それらのいずれも省略できる場合は機能しないことです。
バラッグ。
a)すべてのオプションパラメータは同じ型です。
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)オプションのパラメータの種類は異なる場合があります。
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");
このアプローチの主な欠点は、オプションのパラメータが異なる型である場合、静的型チェックを失うことです。さらに、各パラメータの意味が異なる場合は、それらを区別する方法が必要です。
NULL。 以前のアプローチの制限に対処するために、null値を許可してからメソッド本体の各パラメータを分析することができます。
void foo(String a, Integer b, Integer c) {
b = b != null ? b : 0;
c = c != null ? c : 0;
//...
}
foo("a", null, 2);
すべての引数値を指定する必要がありますが、デフォルトの値はnullになることがあります。
オプションのクラス。 このアプローチはnullに似ていますが、デフォルト値を持つパラメータにJava 8 Optionalクラスを使用します。
void foo(String a, Optional<Integer> bOpt) {
Integer b = bOpt.isPresent() ? bOpt.get() : 0;
//...
}
foo("a", Optional.of(2));
foo("a", Optional.<Integer>absent());
オプションは呼び出し側に対してメソッドコントラクトを明示的にしますが、そのようなシグネチャは冗長すぎることがあります。
更新:Java 8にはクラスJava.util.Optional
が追加設定なしで含まれているので、Java 8ではこの特別な理由でguavaを使用する必要はありません。ただし、メソッド名は少し異なります。
ビルダーパターン。 ビルダーパターンはコンストラクターに使用され、別の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();
地図。 パラメータの数が多すぎ、ほとんどのデフォルト値が通常使用される場合は、メソッドの引数をそれらの名前/値のマップとして渡すことができます。
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では、このアプローチはより簡単になりました。
@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"));
あなたが望ましい結果を達成するためにあなたがこれらのアプローチのどれでも組み合わせることができることに注意してください。
あなたはこのようなものを使うことができます:
public void addError(String path, String key, Object... params) {
}
params
変数はオプションです。それはオブジェクトのnull許容配列として扱われます。
奇妙なことに、私はドキュメンテーションの中でこれについて何かを見つけることができませんでした、しかしそれはうまくいきます!
これは、Java 1.5以降では「新規」です(Java 1.4以前ではサポートされていません)。
私はユーザーbhootがこれをあまりにも下で言及しているのを見ます。
Java 5.0にはオプションのパラメータがあります。関数をこのように宣言するだけです。
public void doSomething(boolean... optionalFlag) {
//default to "false"
//boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
あなたは今doSomething();
またはdoSomething(true);
で呼び出すことができます。
残念ながら、Javaはデフォルトのパラメータを直接サポートしていません。
ただし、私は一連のJavaBeanアノテーションを作成しました。そのうちの1つは、次のようなデフォルトのパラメータをサポートしています。
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とオーバーロードが言及されています。もう1つの選択肢はBuilderパターンです。これは次のようになります。
MyObject my = new MyObjectBuilder().setParam1(value)
.setParam3(otherValue)
.setParam6(thirdValue)
.build();
ただし、そのパターンは、コンストラクタでオプションのパラメータが必要な場合に最も適しています。
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);
}
}
}
それはあなたが何を達成したいのかに依存するでしょう、可変引数またはメソッドオーバーロードはほとんどのシナリオを解決するべきです。ここにそれらを使用する方法のいくつかの良い例があります:
http://blog.sleekface.com/in/Java-core/method-with-optional-parameters/ /
しかし、メソッドのオーバーロードをやり過ぎないように注意してください。混乱を招きます。
3つのドット :を使う
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);
(@ VitaliiFedorenkoの回答に基づく)
このようにメソッドオーバーロードを使ってできることがあります。
public void load(String name){ }
public void load(String name,int age){}
@Nullableアノテーションも使えます
public void load(@Nullable String name,int age){}
最初のパラメータとして単にnullを渡します。
同じ型変数を渡している場合はこれを使用できます
public void load(String name...){}
オーバーロードは問題ありませんが、デフォルト値が必要な変数がたくさんある場合は、次のようになります。
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によって提供される変数引数を使用することをお勧めします。説明は link です。
Javaは1.8のオプションをサポートするようになりました。Androidでのプログラミングにこだわっているので、コードをリファクタリングしてオプションの型を使用できるようになるまでnullを使用します。
Object canBeNull() {
if (blah) {
return new Object();
} else {
return null;
}
}
Object optionalObject = canBeNull();
if (optionalObject != null) {
// new object returned
} else {
// no new object returned
}
あなたはこのようなあなたのオプションの値を含むためにビルダーのように働くクラスを使うことができます。
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);
}
好きに使う
foo(o -> o.setSomeString("something").setSomeInt(5));
出力は
someString = something, someInt = 5
あなたがfoo(o -> {});
のようにそれを呼ばなければならないすべてのオプションの値をスキップするか、あなたが望むなら、あなたはオプションのパラメータをとらない2番目のfoo()
メソッドを作成することができます。
この方法を使用すると、あいまいさなしに任意の順序でオプションの値を指定できます。可変引数とは異なり、異なるクラスのパラメータを持つこともできます。 Optionsクラスを作成するためにアノテーションとコード生成を使うことができるならば、このアプローチはさらに良いでしょう。
これは昔の質問ですが、実際のOptional型が導入される前であっても構いませんが、最近ではいくつか考慮することができます。 GoogleのGuavaなどのサードパーティ製のライブラリから。パラメータ/引数としてオプションを使用することは、主な目的が戻り時間としてそれを使用することであったので、使い過ぎとして考えることができます。
参照: https://itcodehub.blogspot.com/2019/06/using-optional-type-in-Java.html
デフォルト引数はJavaでは使用できません。 C#、C++、Pythonでは、それらを使用することができます。
Javaでは、デフォルトのパラメータを持つメソッドの代わりに、2つのメソッド(関数)を使用する必要があります。
例:
Stash(int size);
Stash(int size, int initQuantity);
Methodオーバーロードまたは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;
}