Java opcjonalne parametry
Jak używać opcjonalnych parametrów w Javie? Jaka Specyfikacja obsługuje opcjonalne parametry?
16 answers
Varargs mógłby to zrobić (w pewien sposób). Poza tym należy podać wszystkie zmienne w deklaracji metody. Jeśli chcesz, aby zmienna była opcjonalna, możesz przeciążyć metodę za pomocą podpisu, który nie wymaga parametru.
private boolean defaultOptionalFlagValue = true;
public void doSomething(boolean optionalFlag) {
...
}
public void doSomething() {
doSomething(defaultOptionalFlagValue);
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-05-20 10:27:13
Istnieje kilka sposobów symulowania opcjonalnych parametrów w Javie:
-
Metoda przeciążenia.
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");
Jednym z ograniczeń tego podejścia jest to, że nie działa, jeśli masz dwa opcjonalne parametry tego samego typu i każdy z nich można pominąć.
-
Varargs.
A) wszystkie opcjonalne parametry są tego samego typu:
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) typy parametrów opcjonalnych mogą być różne:
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");
Główny wadą tego podejścia jest to, że jeśli opcjonalne parametry są różnych typów, tracisz sprawdzanie typu statycznego. Ponadto, jeśli każdy parametr ma inne znaczenie, musisz w jakiś sposób je rozróżnić.
-
Nulls. aby rozwiązać ograniczenia poprzednich podejść, możesz zezwolić na wartości null, a następnie przeanalizować każdy parametr w ciele metody:
void foo(String a, Integer b, Integer c) { b = b != null ? b : 0; c = c != null ? c : 0; //... } foo("a", null, 2);
Teraz muszą być podane wszystkie wartości argumentów, ale domyślne mogą być null.
-
Klasa opcjonalna. to podejście jest podobne do NULL, ale używa opcjonalnej klasy Java 8 dla parametrów, które mają wartość domyślną:
void foo(String a, Optional<Integer> bOpt) { Integer b = bOpt.isPresent() ? bOpt.get() : 0; //... } foo("a", Optional.of(2)); foo("a", Optional.<Integer>absent());
Opcjonalne sprawia, że umowa metody jest jednoznaczna dla rozmówcy, jednak może się okazać, że taki podpis jest zbyt gadatliwy.
Update: Java 8 zawiera klasę
java.util.Optional
po wyjęciu z pudełka, więc nie ma potrzeby używania guava z tego konkretnego powodu w Javie 8. Nazwa metody jest nieco inna chociaż. -
Wzór budowniczego. wzorzec builder jest używany dla konstruktorów i jest zaimplementowany poprzez wprowadzenie oddzielnej klasy 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();
-
Mapy. gdy liczba parametrów jest zbyt duża i dla większości z nich zwykle używane są wartości domyślne, można przekazać argumenty metody jako mapę ich nazw/wartości:
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"));
Należy pamiętać, że można połączyć dowolne z tych podejść, aby osiągnąć pożądany wynik.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-02 02:36:14
Możesz użyć czegoś takiego:
public void addError(String path, String key, Object... params) {
}
Zmienna params
jest opcjonalna. Jest traktowana jako nullable tablica obiektów.
Jest to "nowość" w Javie 1.5 i nowszej (nie jest obsługiwane w Javie 1.4 lub wcześniejszej).
Widzę, że user bhoot wspomniał o tym również poniżej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-03 21:41:36
W Javie 5.0 są opcjonalne parametry. Po prostu zadeklaruj swoją funkcję w ten sposób:
public void doSomething(boolean... optionalFlag) {
//default to "false"
//boolean flag = (optionalFlag.length >= 1) ? optionalFlag[0] : false;
}
Możesz zadzwonić z doSomething();
lub doSomething(true);
Teraz.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-29 13:36:48
Niestety Java nie obsługuje bezpośrednio domyślnych parametrów.
Jednak napisałem zestaw adnotacji JavaBean, a jedna z nich obsługuje domyślne parametry, takie jak:
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);
}
Procesor adnotacji generuje przeciążenia metody, aby prawidłowo ją obsługiwać.
Zobacz http://code.google.com/p/javadude/wiki/Annotations
Pełny przykład na http://code.google.com/p/javadude/wiki/AnnotationsDefaultParametersExample
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-08 17:00:09
Nie ma opcjonalnych parametrów w Javie. Możesz przeciążać funkcje, a następnie przekazywać wartości domyślne.
void SomeMethod(int age, String name) {
//
}
// Overload
void SomeMethod(int age) {
SomeMethod(age, "John Doe");
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-08 16:18:10
Warargi i przeciążenia zostały wymienione. Inną opcją jest wzorzec konstruktora, który wyglądałby mniej więcej tak:
MyObject my = new MyObjectBuilder().setParam1(value)
.setParam3(otherValue)
.setParam6(thirdValue)
.build();
Chociaż ten wzór byłby najbardziej odpowiedni, gdy potrzebujesz opcjonalnych parametrów w konstruktorze.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-08 17:05:21
W JDK>1.5 można go używać w ten sposób;
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);
}
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-24 10:44:38
To zależy od tego, co chcesz osiągnąć, varargs lub metody przeciążenia powinny rozwiązać większość scenariuszy.
Ale należy pamiętać, aby nie nadużywać metody przeciążenia. to wprowadza zamieszanie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-22 10:19:36
Wersja skrócona:
Używając trzech kropek :
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);
(na podstawie odpowiedzi @ VitaliiFedorenko)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-11-27 19:18:35
Możesz zrobić coś używając metody przeciążania w ten sposób.
public void load(String name){ }
public void load(String name,int age){}
Możesz również użyć adnotacji @ Nullable
public void load(@Nullable String name,int age){}
Po prostu podaj null jako pierwszy parametr.
Jeśli przekazujesz zmienną tego samego typu, możesz użyć tego
public void load(String name...){}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-19 11:33:36
Przeciążenie jest w porządku, ale jeśli istnieje wiele zmiennych, które wymagają wartości domyślnej, skończysz z :
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) { }
Proponuję więc użyć argumentu zmiennej dostarczonego przez Javę. Oto link do wyjaśnienia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-16 02:24:37
Java obsługuje teraz opcje w 1.8, utknąłem z programowaniem na Androidzie, więc używam null, dopóki nie będę mógł refaktorować kodu, aby użyć opcjonalnych typów.
Object canBeNull() {
if (blah) {
return new Object();
} else {
return null;
}
}
Object optionalObject = canBeNull();
if (optionalObject != null) {
// new object returned
} else {
// no new object returned
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-20 07:04:27
Możesz użyć klasy, która działa podobnie jak builder, aby zawierać opcjonalne wartości, takie jak ta.
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);
}
Użyj jak
foo(o -> o.setSomeString("something").setSomeInt(5));
Wyjście to
someString = something, someInt = 5
Aby pominąć wszystkie opcjonalne wartości, musisz wywołać je tak, jak foo(o -> {});
lub jeśli wolisz, możesz utworzyć drugą metodę foo()
, która nie przyjmuje opcjonalnych parametrów.
Za pomocą tego podejścia można określić wartości opcjonalne w dowolnej kolejności bez żadnych niejasności. Można również mieć parametry różnych klas w przeciwieństwie do z varargsem. Takie podejście byłoby jeszcze lepsze, gdybyś mógł użyć adnotacji i generowania kodu do utworzenia klasy Options.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-12-15 23:49:01
Argumenty domyślne nie mogą być używane w Javie i C#. Gdzie w C++ i Pythonie możemy z nich korzystać..
W Javie musimy używać dwóch metod (funkcji) zamiast jednej z domyślnymi parametrami.
Przykład:
Stash(int size);
Stash(int size, int initQuantity);
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-11 14:22:33
Możemy wykonać opcjonalny parametr metodą przeciążenia lub za pomocą typu danych...
|*| metoda przeciążenia:
RetDtaTyp NamFnc(String NamPsgVar)
{
// |* CodTdo *|
return RetVar;
}
RetDtaTyp NamFnc(String NamPsgVar)
{
// |* CodTdo *|
return RetVar;
}
RetDtaTyp NamFnc(int NamPsgVar1, String NamPsgVar2)
{
// |* CodTdo *|
return RetVar;
}
Najprostszym sposobem jest
/ * / DataType... może być opcjonalnym parametrem
RetDtaTyp NamFnc(int NamPsgVar, String... SrgOpnPsgVar)
{
if(SrgOpnPsgVar.length == 0) SrgOpnPsgVar = DefSrgVar;
// |* CodTdo *|
return RetVar;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-23 10:32:02