Java, değişkenlerin yeniden atanmasını önlemek için değişkenlerin (alanlar/yerel ayarlar/parametreler)
final olarak işaretlenmesine izin verir. Bazı niteliklerin - ya da tüm bir sınıfın - değişmez olup olmadığını çabucak görmeme yardımcı olduğundan, onu alanlarla çok yararlı buluyorum.
Öte yandan, yerliler ve parametreler için çok daha az kullanışlı buluyorum ve genellikle yeniden atanmayacak olsalar bile ([gerektiğinde bariz istisna hariç) bunları
final olarak işaretlemekten kaçınıyorum. iç sınıfta kullanılır). Son zamanlarda, ancak, teknik olarak daha fazla bilgi sağlar sanırım ne zaman, final kullanılan kod geldi.
Programlama tarzımdan artık emin değilim,
final'ı herhangi bir yere uygulamanın diğer avantajları ve dezavantajları nelerdir, en yaygın endüstri tarzı nedir ve nedenini merak ediyorum.
final ile aynı şekilde kullanıyorum. Bana göre yerel değişkenler ve yöntem parametreleri üzerinde gereksiz görünüyor ve yararlı ekstra bilgiler içermiyor.
Önemli bir şey, her biri tek bir görev yapan yöntemlerimi kısa ve temiz tut için çabalamaktır. Bu nedenle, yerel değişkenlerimin ve parametrelerimin kapsamı çok sınırlıdır ve yalnızca tek bir amaç için kullanılır. Bu, onları yanlışlıkla yeniden atama şansını en aza indirir.
Ayrıca, bildiğiniz gibi,
final, (birincil olmayan) bir değişkenin değerini/durumunu değiştiremeyeceğinizi garanti etmez. Yalnızca referansını başlatıldıktan sonra o nesneye yeniden atayamazsınız. Başka bir deyişle, sadece ilkel veya değişmez tipteki değişkenlerle sorunsuz çalışır. Düşünmek
final String s = "forever"; final int i = 1; final Map<String, Integer> m = new HashMap<String, Integer>(); s = "never"; // compilation error! i++; // compilation error! m.put(s, i); // fine
Bu, çoğu durumda kodun içinde ne olduğunu anlamanın daha kolay olmadığı ve bunun yanlış anlaşılmasının aslında algılanması zor olan küçük hatalara neden olabileceği anlamına gelir.
Java programlama stiliniz ve düşünceleriniz iyi - orada kendinizden şüphe etmenize gerek yok.
Öte yandan, yerliler ve parametreler için çok daha az kullanışlı buluyorum ve genellikle tekrar atanmayacak olsalar bile onları nihai olarak işaretlemekten kaçınıyorum (bir iç sınıfta kullanılması gerektiğinde bariz istisna hariç) ).
Bu yüzden
final anahtar kelimesini kullanmalısınız. SIZ asla yeniden atanmayacağını biliyorsunuz, ancak başka kimse bunu bilmiyor.
final kullanılması, kodunuzu biraz daha belirgin hale getirir.
Mümkün olan her yerde
final/
const kullanmanın avantajlarından biri, kodunuzun okuyucusu için zihinsel yükü azaltmasıdır.
Değer/referansın daha sonra asla değiştirilmeyeceğinden emin olabilir. Bu nedenle, hesaplamayı anlamak için değişikliklere dikkat etmesi gerekmez.
Saf fonksiyonel programlama dillerini öğrendikten sonra bu konudaki fikrimi değiştirdim. Çocuk, ne bir rahatlama, her zaman başlangıç değerini tutmak için bir "değişken" güvenebilirsiniz.
Ben yöntem parametreleri ve yerel değişkenler
final kod gürültü olarak düşünün. Java yöntem bildirimleri oldukça uzun olabilir (özellikle jenerikler için) - bunları artık yapmaya gerek yoktur.
Birim testleri düzgün bir şekilde yazılırsa, "zararlı" parametrelere atama yapılır, bu yüzden asla aslında sorun olmamalıdır. Görsel netlik, birim testlerinizin kapsamı yetersiz olduğu için alınmayan olası hatalarından kaçınmaktan daha önemlidir.
FindBugs ve CheckStyle gibi, parametrelere veya yerel değişkenlere atama yapılırsa, bu tür şeyleri derinden önemsiyorsanız yapıyı kesecek şekilde yapılandırılabilen araçlar.
Tabii ki, onları nihai yapmak için need yaparsanız, örneğin değeri anonim bir sınıfta kullandığınız için, o zaman sorun değil - bu en basit çözümdür.
Parametrelerinize ekstra anahtar kelimeler eklemenin ve böylece IMHO'nun kamufle edilmesinin bariz etkisinin yanı sıra, yöntem parametrelerine final eklemek genellikle yöntem gövdesindeki kodu daha az okunabilir hale getirebilir, bu da kodu daha da kötüleştirir - "iyi", kod okunabilir ve olabildiğince basit olmalıdır. Aksine bir örnek için, büyük/küçük harfe duyarlı bir şekilde çalışmam gereken bir yöntemim olduğunu varsayalım.
final olmadan:
public void doSomething(String input) { input = input.toLowerCase(); // do a few things with input }
Basit. Temiz. Herkes neler olduğunu biliyor.
Şimdi 'final', seçenek 1:
public void doSomething(final String input) { final String lowercaseInput = input.toLowerCase(); // do a few things with lowercaseInput }
final parametrelerini oluştururken kodlayıcı, kod ekleme işlemini orijinal değerle çalıştığını düşünmekten alıkoyarken, kodun daha aşağıya doğru
input yerine
lowercaseInput kullanma riski eşittir , bunu yapmamalı ve korunmayacak, çünkü onu kapsam dışına çıkaramazsınız (hatta yine de yardımcı olsa bile
null 'a
input atayabilirsiniz).
'Final' ile seçenek 2:
public void doSomething(final String input) { // do a few things with input.toLowerCase() }
Şimdi daha da fazla kod gürültüsü oluşturduk ve
toLowerCase() n kez çağırmak zorunda kaldığımız bir performans isabeti sunduk.
'Final' ile seçenek 3:
public void doSomething(final String input) { doSomethingPrivate(input.toLowerCase()); } /** @throws IllegalArgumentException if input not all lower case */ private void doSomethingPrivate(final String input) { if (!input.equals(input.toLowerCase())) { throw new IllegalArgumentException("input not lowercase"); } // do a few things with input }
Kod gürültüsü hakkında konuşun. Bu bir tren enkazı. Yeni bir yöntemimiz, gerekli bir istisna bloğumuz var, çünkü diğer kodlar yanlış çağırabilir. İstisnaları kapsayan daha fazla birim testi. Tüm basit ve IMHO tercih ve zararsız bir çizgi önlemek için.
Yöntemlerin o kadar uzun olmaması gerektiği sorunu da kolayca görsel olarak kabul edemez ve bir bakışta parametreye atamanın gerçekleştiğini bilemezsiniz.
Ben iyi bir uygulama/tarzı olduğunu düşünüyorum eğer bir parametreye atamak eğer yöntem her erken, tercihen ilk satır veya düz temel giriş kontrolünden hemen sonra, etkili yerine için tamamını yöntem, yöntem içinde tutarlı bir etkisi vardır. Okuyucular, herhangi bir ödevin açık (imza beyanına yakın) ve tutarlı bir yerde olmasını beklemektedirler, bu da final eklemenin kaçınmaya çalıştığı sorunu büyük ölçüde azaltır. Aslında nadiren parametrelere atarım, ancak yaparsam her zaman bir yöntemin üstünde yaparım.
final 'ın sizi ilk başta göründüğü gibi korumadığını da unutmayın:
public void foo(final Date date) { date.setTime(0); // code that uses date }
final parametre tipi ilkel veya değiştirilemezse sizi tamamen korumaz.
Eclipse'in her bir yerel değişkenin önüne
final koymasına izin verdim, çünkü programı okumayı daha kolay hale getirmeyi düşünüyorum. Parametre listesini mümkün olduğunca kısa tutmak istediğim için parametrelerle yapmıyorum, ideal olarak bir satıra sığmalıdır.