Natknąłem się na kod Java, który miał następującą strukturę:
public MyParameterizedFunction(String param1, int param2)
{
this(param1, param2, false);
}
public MyParameterizedFunction(String param1, int param2, boolean param3)
{
//use all three parameters here
}
Wiem, że w C ++ mogę przypisać parametrowi wartość domyślną. Na przykład:
void MyParameterizedFunction(String param1, int param2, bool param3=false);
Czy Java obsługuje taką składnię? Czy są jakieś powody, dla których ta dwustopniowa składnia jest lepsza?
public MyParameterizedFunction(String param1, int param2)
to konstruktor, a nie metoda, deklaracja.Odpowiedzi:
Nie, struktura, którą znalazłeś, to sposób, w jaki Java ją obsługuje (to znaczy z przeciążeniem zamiast parametrów domyślnych).
W przypadku konstruktorów zobacz Poradnik dla efektywnego języka Java: Podręcznik programowania w języku 1 (rozważ konstruktor statycznych metod fabrycznych zamiast konstruktorów), jeśli przeciążenie staje się skomplikowane. W przypadku innych metod pomocne może być zmiana nazwy niektórych przypadków lub użycie obiektu parametru. To wtedy masz wystarczająco złożoność, że odróżnienie jest trudne. Zdecydowanym przypadkiem jest rozróżnienie przy użyciu kolejności parametrów, a nie tylko liczby i typu.
źródło
static
w 2015 r. wszystko jest uważane za szkodliwe. Wpisz bezpieczne, płynneBuilder
instancje, które egzekwują pełne i ważne umowy o budowę, są teraz znacznie lepszym rozwiązaniem.new
. Są one cały czas używane w nowym kodzie. Konstruktory prostych obiektów o wartości są często wynikiem nadmiernej inżynierii.Nie, ale możesz użyć Wzorca konstruktora , jak opisano w odpowiedzi na Przepełnienie stosu .
Jak opisano w połączonej odpowiedzi, wzorzec konstruktora umożliwia pisanie kodu podobnego
w których niektóre pola mogą mieć wartości domyślne lub być opcjonalne.
źródło
Student s1 = new Student().age(16);
to sprawiłoby, że miałbyś Ucznia bez imienia, co może być złe. Jeśli nie jest źle, to twoje rozwiązanie jest w porządku.Istnieje kilka sposobów symulacji domyślnych parametrów w Javie:
Przeciążenie metody.
Jednym z ograniczeń tego podejścia jest to, że nie działa, jeśli masz dwa opcjonalne parametry tego samego typu, a każdy z nich można pominąć.
Varargs.
a) Wszystkie parametry opcjonalne są tego samego typu:
b) Rodzaje parametrów opcjonalnych mogą być różne:
Główną wadą tego podejścia jest to, że jeśli parametry opcjonalne są różnych typów, tracisz sprawdzanie typu statycznego. Ponadto, jeśli każdy parametr ma inne znaczenie, potrzebujesz sposobu na ich rozróżnienie.
Zero Aby rozwiązać ograniczenia poprzednich podejść, możesz zezwolić na wartości zerowe, a następnie przeanalizować każdy parametr w treści metody:
Teraz należy podać wszystkie wartości argumentów, ale wartości domyślne mogą być zerowe.
Klasa fakultatywna To podejście jest podobne do wartości zerowych, ale wykorzystuje klasę opcjonalną Java 8 dla parametrów o wartości domyślnej:
Opcjonalne sprawia, że metoda dzwoniąca jest jawna dla osoby dzwoniącej, jednak taki podpis może okazać się zbyt szczegółowy.
Wzór konstruktora. Wzorzec konstruktora jest używany dla konstruktorów i jest implementowany przez wprowadzenie oddzielnej klasy konstruktora:
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żesz przekazać argumenty metody jako mapę ich nazw / wartości:
Pamiętaj, że możesz połączyć dowolne z tych podejść, aby osiągnąć pożądany rezultat.
źródło
return this
zrobić? Ponadto,FooBuilder().setA("a").build();
ponieważ skoro (z definicji) konstruktor jest wywoływany jako pierwszy iFooBuilder()
zwraca wartość, czy to nie oznacza,.setA("a"):
że nie ma szansy na wywołanie?return this
zwraca ten sam obiekt, na którym wywołano metodę (w przykładzieFooBuilder
). Umożliwia to łączenie metod w jednej instrukcji działającej na ten sam obiekt:new FooBuilder().setA(..).setB(..).setC(..)
itp. W przeciwieństwie do wywoływania każdej metody w osobnej instrukcji.new FooBuilder()
zwracaFooBuilder
obiekt, do któregosetA
wywoływana jest metoda. JaksetB
się nie nazywa,this.b
zachowuje wartość domyślną. Wreszciebuild
metoda jest wywoływana na tymFooBuilder
obiekcie.build
Metoda tworzy i zwracaFoo
obiekt, który jest ustawiony do zmiennejFoo foo
. Zauważ, żeFooBuilder
obiekt nie jest przechowywany w żadnej zmiennej.Niestety nie.
źródło
Niestety tak.
można napisać w Javie 1.5 jako:
Ale czy powinieneś polegać na tym, jak się czujesz na temat generowania kompilatora
dla każdego połączenia.
W przypadku wielu parametrów domyślnych:
można napisać w Javie 1.5 jako:
Jest to zgodne ze składnią C ++, która dopuszcza parametry domyślne tylko na końcu listy parametrów.
Poza składnią istnieje różnica w tym, że ma to sprawdzanie typu w czasie wykonywania pod kątem parametrów domyślnych, a typ C ++ sprawdza je podczas kompilacji.
źródło
assert
kodu produkcyjnego. Rzuć wyjątek.Nie, ale możesz bardzo łatwo je emulować. Co w C ++ było:
W Javie będzie to funkcja przeciążona:
Wcześniej wspomniano, że domyślne parametry powodowały niejednoznaczne przypadki przeciążenia funkcji. To po prostu nieprawda, widzimy w przypadku C ++: tak, może może tworzyć niejednoznaczne przypadki, ale problem ten można łatwo rozwiązać. Po prostu nie został opracowany w Javie, prawdopodobnie dlatego, że twórcy chcieli znacznie prostszego języka, jakim był C ++ - jeśli mieli rację, to kolejne pytanie. Ale większość z nas nie uważa, że używa Javy ze względu na jej prostotę.
źródło
Możesz to zrobić w Scali, która działa na JVM i jest kompatybilna z programami Java. http://www.scala-lang.org/
to znaczy
źródło
Nie , ale najprostszym sposobem na wdrożenie tego jest:
lub zamiast operatora trójskładnikowego możesz użyć
if
:źródło
Być może stwierdzam tu oczywistość, ale dlaczego po prostu nie wdrożyć parametru „domyślnego”?
domyślnie użyłbyś albo
a jeśli nie chcesz używać domyślnej, skorzystasz
źródło
//This is better public class Foo() { /* This does something */ public void func(String s){ //do something } /* This does something else with b */ public void func(String s, boolean b){ // b was passed } }
//Than this public class Foo() { /* This does something unless b = value, then it does something else */ public void func(String s, boolean b = value){ If (b){ // Do Something } else{ // Do something else } } }
Jak wspomniano Scalę, Kotlin również jest wart wspomnienia. W funkcji Kotlin parametry mogą mieć również wartości domyślne, a nawet mogą odnosić się do innych parametrów:
Podobnie jak Scala, Kotlin działa na JVM i może być łatwo zintegrowany z istniejącymi projektami Java.
źródło
Nie.
Możesz osiągnąć to samo zachowanie, przekazując obiekt, który ma inteligentne ustawienia domyślne. Ale znowu to zależy od tego, co masz pod ręką.
źródło
Nie. Ogólnie Java nie ma dużo (żadnego) cukru syntaktycznego, ponieważ próbowali stworzyć prosty język.
źródło
const
igoto
byłyby zastrzeżone słowa kluczowe, których nie ma w implementacji? - Szczególnieconst
gorzko tęsknię -final
nie ma zastępstwa i wiedzieli o tym. - A jeśli podjąłeś świadomą decyzję, aby nigdy nie wdrożyćgoto
, nie musisz rezerwować słowa kluczowego. - A później w zespole Java oszukiwał, czyniąc oparty na Labelbreak
icontinue
tak potężny jak Pascalgoto
.Zamiast używać:
Możesz skorzystać z opcjonalnej funkcjonalności java, mając jedną metodę:
Główną różnicą jest to, że musisz używać klas opakowań zamiast pierwotnych typów Java, aby umożliwić
null
wprowadzanie danych.Boolean
zamiastboolean
,Integer
zamiastint
i tak dalej.źródło
To nie jest obsługiwane, ale istnieje kilka opcji, takich jak użycie wzorca obiektu parametru z odrobiną cukru składniowego:
W tym przykładzie konstruujemy
ParameterObject
wartości domyślne i zastępujemy je w sekcji inicjalizacji instancji klasy{ param1 = 10; param2 = "bar";}
źródło
Wypróbuj to rozwiązanie:
źródło
Możesz użyć Java Method Invocation Builder, aby automatycznie wygenerować builder z wartościami domyślnymi.
Po prostu dodaj @GenerateMethodInvocationBuilder do klasy lub interfejsu, a @Default do parametrów w metodach, w których chcesz mieć wartości domyślne. Konstruktor zostanie wygenerowany w czasie kompilacji przy użyciu wartości domyślnych określonych w adnotacjach.
Następnie możesz wywołać metody.
Lub ustaw dowolną z wartości domyślnych na coś innego.
źródło
Podobne podejście do https://stackoverflow.com/a/13864910/2323964, które działa w Javie 8, polega na użyciu interfejsu z domyślnymi modułami pobierającymi. Będzie to bardziej szczegółowe białe znaki, ale można z niego wyśmiewać i jest to świetne, gdy masz kilka przypadków, w których naprawdę chcesz zwrócić uwagę na parametry.
źródło
Spędziłem teraz trochę czasu, aby dowiedzieć się, jak tego używać z metodami, które zwracają wartości, i jak dotąd nie widziałem żadnych przykładów, pomyślałem, że przydatne może być dodanie tego tutaj:
źródło
Tak to zrobiłem ... być może nie jest to tak wygodne jak „opcjonalny argument” przeciwko zdefiniowanemu parametrowi, ale wykonuje zadanie:
Zauważ, że mogę wywołać tę samą nazwę metody za pomocą tylko łańcucha lub mogę wywołać ją za pomocą łańcucha i wartości logicznej. W takim przypadku ustawienie wipeClean na true spowoduje zastąpienie całego tekstu w moim obiekcie TextArea podanym ciągiem. Ustawienie wipeClean na false lub pomijanie go razem powoduje dołączenie dostarczonego tekstu do TextArea.
Zauważ też, że nie powtarzam kodu w dwóch metodach, po prostu dodaję funkcję resetowania TextArea, tworząc nową metodę o tej samej nazwie tylko z dodaną wartością logiczną.
Myślę, że jest to trochę czystsze niż gdyby Java podała „opcjonalny argument” dla naszych parametrów, ponieważ musielibyśmy wtedy kodować wartości domyślne itp. W tym przykładzie nie muszę się tym martwić. Tak, dodałem jeszcze jedną metodę do mojej klasy, ale na dłuższą metę łatwiej jest ją czytać, moim skromnym zdaniem.
źródło
NIE, Ale mamy alternatywę w postaci przeciążenia funkcji.
wywoływany, gdy nie przekazano żadnego parametru
wywoływane, gdy parametr „a” został przekazany
wywoływane, gdy parametr b minie
źródło
Istnieje pół tuzina lub lepszych problemów, takich jak ten, w końcu dochodzisz do statycznego wzorca fabrycznego ... zobacz o tym API kryptograficzne. Sortuj trudne do wyjaśnienia, ale pomyśl o tym w ten sposób: Jeśli masz konstruktor, domyślny lub inny, jedynym sposobem propagowania stanu poza nawiasy klamrowe jest albo użycie logicznej wartości isValid; (wraz z wartością null jako wartością domyślną v nieudany konstruktor) lub zgłasza wyjątek, który nigdy nie jest pouczający, gdy odzyskuje go od użytkowników pola.
Kod Poprawnie, do diabła, piszę tysiące konstruktorów linii i robię to, czego potrzebuję. Używam isValid przy budowie obiektów - innymi słowy, konstruktory dwuwierszowe - ale z jakiegoś powodu migruję do statycznego wzorca fabrycznego. Wydaje mi się, że możesz wiele zdziałać, jeśli używasz metody, nadal występują problemy z synchronizacją (), ale wartości domyślne można lepiej zastąpić (bezpieczniej)
Myślę, że musimy tutaj zająć się kwestią zerową jako wartością domyślną względem czegoś String one = new String (""); jako zmienną składową, a następnie sprawdzanie wartości null przed przypisaniem ciągu przekazywanego do konstruktora.
Niezwykła ilość surowej, stratosferycznej informatyki wykonanej w Javie.
C ++ i tak dalej ma biblioteki dostawców, tak. Java może wyprzedzić je na dużych serwerach ze względu na ogromny zestaw narzędzi. Studiuj statyczne bloki inicjalizujące, zostań z nami.
źródło
Nie jest obsługiwany w Javie jak w innym języku np. Kotlin.
źródło
Możesz użyć następujących-
źródło