2010-11-12 8 views
53

Jaka jest różnica między ostatecznym kodem poniżej. Czy jest jakaś przewaga w deklarowaniu argumentów jako ostatecznych?Tworzenie argumentów metody java jako ostatecznej

public String changeTimezone(Timestamp stamp, Timezone fTz, Timezone toTz){ 
    return .... 
} 

public String changeTimezone(final Timestamp stamp, final Timezone fTz, 
     final Timezone toTz){ 
    return .... 
} 
+3

Istnieją analizatory kodów, które ostrzegają, jeśli parametr zostanie ponownie użyty lub ponownie przypisany. (Tak samo dla zmiennych lokalnych) IMHO, jest to lepszy sposób na wychwycenie takich parametrów, jeśli uznasz, że ich zmiana jest niepożądana. –

+0

Możliwy duplikat [Dlaczego powinienem używać słowa kluczowego "final" w parametrze metody w Javie?] (Https://stackoverflow.com/questions/500508/why-should-i-use-the-keyword-final-on -a-method-parameter-in-java) –

Odpowiedz

75

Jako formalny parametr metody jest zmienną lokalną, można uzyskać do niego dostęp z wewnętrznych anonimowych klas tylko wtedy, gdy są one zadeklarowane jako ostateczne.

To pozwala uniknąć oświadczając inną zmienną lokalną końcowy w organizmie metoda:

void m(final int param) { 
     new Thread(new Runnable() { 
      public void run() { 
       System.err.println(param); 
      } 
     }).start(); 
    } 
+18

+1: Jest to ważny przypadek użycia i jedyny czas, kiedy * potrzebujesz * go. (Reszta czasu to tylko kwestia tego, co jest wygodne do pomocy programistom.) –

+3

Czy mogę zapytać o uzasadnienie tego? – KodeWarrior

+11

Koniec z Java Java 8. –

10

To nie ma większego znaczenia. To po prostu oznacza, że ​​nie można napisać:

stamp = null; 
fTz = new ...; 

ale nadal można napisać:

stamp.setXXX(...); 
fTz.setXXX(...); 

To głównie wskazówką dla programisty, który następuje ci konserwacyjnych, które nie zamierzają przypisać nowa wartość parametru gdzieś w środku metody, gdzie nie jest ona oczywista i może powodować zamieszanie.

15

Finał uniemożliwia przypisanie nowej wartości do zmiennej, co może być pomocne przy łapaniu literówek. Stylistycznie możesz chcieć zachować niezmienione parametry i przypisywać je tylko do zmiennych lokalnych, więc finał pomoże wymusić ten styl.

Muszę przyznać, że rzadko pamiętam, aby używać parametrów końcowych, może powinienem.

public int example(final int basicRate){ 
    int discountRate; 

    discountRate = basicRate - 10; 
    // ... lots of code here 
    if (isGoldCustomer) { 
     basicRate--; // typo, we intended to say discountRate--, final catches this 
    } 
    // ... more code here 

    return discountRate; 
} 
0

Jest to po prostu konstrukcja w języku Java, aby pomóc Ci zdefiniować kontrakt i trzymać się go. Podobna dyskusja tutaj: http://c2.com/cgi/wiki?JavaFinalConsideredEvil

BTW - (jak mówi twiki), oznaczanie argumentów jako ostatecznych jest generalnie zbędne, jeśli przestrzegasz zasad dobrego programowania i zmienia się przypisanie/przedefiniowanie przychodzących odwołań do argumentów.

W najgorszym przypadku, jeśli ponownie zdefiniujesz odniesienie args, nie wpłynie to na faktyczną wartość przekazywaną do funkcji - ponieważ przekazano tylko referencję.

2

Ostateczne słowo kluczowe, gdy używa się parametrów/zmiennych w Java oznacza odniesienie jako ostateczna. W przypadku przekazania obiektu do innej metody, system tworzy kopię zmiennej referencyjnej i przekazuje ją do metody. Oznaczając nowe odniesienia jako ostateczne, chronisz je przed zmianą przypisania. Uważa się czasami za dobrą praktykę kodowania.

+1

Muszę coś dodać: jeśli parametry są prymitywne, nie widzę żadnych różnic. Poza tym, jeśli parametry to Kolekcje (lista obiektów ...), to dodanie ostatecznej wersji nie może uniemożliwić ich modyfikacji. – Sam003

+1

Niezmienność jest zawsze pożądaną cechą. Java nie ma go po wyjęciu z pudełka. Dokonywanie zmiennych co najmniej zapewnia integralność referencyjną. – Sid

+0

Zgadzam się. Ale jeśli naprawdę chcemy osiągnąć niezmienność obiektów, możemy spróbować zrobić głęboki klon. – Sam003

19

Fragment The final word on the final keyword

parametry końcowe

Poniższy przykład stwierdza parametry końcowe:

public void doSomething(final int i, final int j) 
{ 
    // cannot change the value of i or j here... 
    // any change would be visible only inside the method... 
} 

końcowy jest tutaj, aby zapewnić dwa indeksów i i j wygrał " t przypadkowo wyzeruj za pomocą metody . Jest to poręczny sposób na ochronę przed podstępnym błędem , który błędnie zmienia wartość Twoich parametrów o .Ogólnie rzecz biorąc, krótkie metody są lepszym sposobem na ochrony przed tą klasą błędów, ale ostateczne parametry mogą być użytecznym dodatkiem do Twojego stylu kodowania.

Zauważ, że parametry końcowe nie są traktowane jako część podpisu metoda i są ignorowane przez kompilator podczas rozwiązywania wywołań metod. Parametry mogą być deklarowane jako ostateczne (lub nie) bez wpływu na sposób nadpisywania metody .

+8

Może być lepiej użyć obiektów niż prymitywów dla tego przykładu, ponieważ prymitywne zmiany będą zawsze widoczne tylko wewnątrz metody. A w przypadku obiektów nadal można je zmienić. Po prostu nie możesz wskazać na nowy obiekt. W rzeczywistości teraz o tym myślę, finał tak naprawdę niczego nie zmienia w porównaniu do pozostawiania go poza zapisaniem deklaracji zmiennej z AIC oraz po tym, jak kompilator wskazał przypadkowe modyfikacje parametrów, których z jakiegoś powodu nie chciałeś modyfikować . –

1

Na ciele tej metody final Hasło uniemożliwi odniesień argument do zmiany przypisania zostać przypadkowo dając Błąd kompilacji w tych sprawach (większość IDE będzie skarżyć od razu). Niektórzy mogą twierdzić, że ogólne użycie, o ile jest to możliwe, przyspieszy sprawę, ale tak nie jest w przypadku ostatnich maszyn wirtualnych maszyn wirtualnych.

0

Mam na myśli oznaczanie zmiennych i pól w ogóle - nie dotyczy tylko argumentów metod. (Metody oznaczania/finał zajęć to zupełnie inna sprawa).

Jest to przysługa dla czytelników/przyszłych opiekunów Twojego kodu. Wraz z rozsądną nazwą zmiennej, jest pomocne i zapewnia czytelnikowi Twój kod, aby zobaczył/zrozumiał, co oznaczają dane zmienne - i zapewnia czytelnikowi, że za każdym razem, gdy zobaczysz zmienną w tym samym zakresie, znaczenie pozostaje to samo, więc nie musi drapać się po głowie, aby zawsze dowiedzieć się, co oznacza zmienna w każdym kontekście. Widzieliśmy zbyt wiele nadużyć "ponownego wykorzystania" zmiennych, co sprawia, że ​​nawet krótki fragment kodu jest trudny do zrozumienia.

-3

Ostatnie słowo kluczowe uniemożliwia przypisanie nowej wartości do parametru. Chciałbym wyjaśnić to prosty przykład

Załóżmy, że mamy metoda

method1() {

Data DateOfBirth = new Date ("01.01.2009");

method2 (dateOfBirth);

method3 (dataOfBirth); }

mehod2 publicznych (Data DateOfBirth) {
....
....
....
}

mehod2 publicznych (Data DateOfBirth) {
....
....
....
}

W powyższym przypadku, jeśli "dateOfBirth" ma przypisaną nową wartość w metodzie 2, to spowodowałoby to nieprawidłowe wyjście z metody3. Ponieważ wartość przekazywana do metody 3 nie jest taka, jaka była przed przekazaniem jej do metody2. Aby uniknąć tego parametru końcowego jest używany do parametrów.

Jest to również jedna z najlepszych praktyk Java Coding.

+5

To nie jest w porządku. Nawet jeśli argument dateOfBirth zostanie zmieniony na inną wartość w method2(), nie będzie to miało wpływu na method2(), ponieważ Java przechodzi przez wartość, a nie przez odniesienie. – Flo

Powiązane problemy