UPPER-CASE'te bir “statik son Kaydedici” bildirilmeli mi?


243

Java'da statik son değişkenler sabittir ve kural büyük harf olması gerektiğidir. Ancak, çoğu insan bir ihlali olarak çıkageldi düşük durumda kaydedicileri beyan olduğunu gördük PMD .

Örneğin:

private static final Logger logger = Logger.getLogger(MyClass.class);

Google'da veya SO'da "statik son kaydedici" için arama yapın ve bunu kendiniz göreceksiniz.

Bunun yerine LOGGER kullanmalı mıyız?


PMD veya Checkstyle, okunabilirliği artırmak için önceden olgunlaşmış naif girişimlerdir, ancak faydadan daha fazla zarara neden olurlar. En okunabilir stil, bağlama göre duruma göre değişebilir. Guava veya JDK src'ye bakın, bunlar herhangi bir katı stil şablonunu takip etmez, ancak profesyoneller tarafından yapılan tartışılmazdır. örnek: DelegatedExecutorService @ docjar.com/html/api/java/util/concurrent/Executors.java.html
Daniel Hári

Sonar Kuralları ( rules.sonarsource.com/java/tag/convention/RSPEC-1312 ) da varprivate static final Logger LOGGER = LoggerFactory.getLogger(Foo.class);
Kenston Choi

Yanıtlar:


306

Logger referansı sabit değil, son bir referanstır ve büyük harfte DEĞİL olmalıdır. Sabit bir VALUE büyük harf olmalıdır.

private static final Logger logger = Logger.getLogger(MyClass.class);

private static final double MY_CONSTANT = 0.0;

42
statik nihai referanslar değişmezlerse sabitlerdir. Bu mantıkla, hiçbir zaman sabit dizginiz olmazdı çünkü herhangi bir statik son dize referanstır.
Jeffrey Blattman

30
Ama java.lang.String olduğunu zaten değişmez ve sınıf özel bir tür (String.intern (), Ilkbahar havuz hakkında belgelere vb bakınız)
Aleksander Adamowski

3
değişmez, inşaattan sonra nesnenin durumunun değişemeyeceği anlamına gelir. aşağıya bakın. kaydediciler mutlaka değiştirilemez.
Jeffrey Blattman

4
Birisi hala bu sorunu önemsiyorsa , talebin büyük harf olup olmadığını ve nerede olmadığını ayırt etmek için lütfen github.com/checkstyle/checkstyle/issues/23 adresinden fikir paylaşın .
Roman Ivanov

2
@Jeach değişmezliğin devletin nasıl değiştiğiyle ilgili olduğunu düşünmüyorum, sadece öyle. dahası, kullanıcı nedir? çalıştıran harici kullanıcı? bir düğmeye basarak bir kullanıcı tarafından değiştirilen durum ile rasgele bir aralıkta bir zamanlayıcı ateşleme ile değiştirilen arasında bir ayrım yapar mısınız? (sanmıyorum).
Jeffrey Blattman

236

Çıtır köpeğin cevabına daha fazla değer katmak için Java Kodlama Stil Kılavuzu bunu 3.3. Alan Adlandırma

Sabit olarak kullanılan alanların adları büyük harfle yazılmalı ve alt sözcükler sözcükleri ayırmalıdır. Aşağıdakilerin sabit olduğu kabul edilir:

  1. Tüm static finalilkel türler ( Tüm arabirim alanlarının kendiliğinden olduğunu unutmayın static final).
  2. static finalAsla " ." (nokta) izlemeyen tüm nesne başvuru türleri .
  3. static final" [" (Açılış köşeli ayraç) tarafından takip edilmeyen tüm diziler .

Örnekler:

MIN_VALUE, MAX_BUFFER_SIZE, OPTIONS_FILE_NAME

Bu kongre sonrasında loggerbir olduğu static finalnoktaya 2'de belirtildiği gibi nesne referansı, ama bunun sebebi olduğu "izledi .Kullanmaya her şey", bir sabit olarak kabul edilemez ve bu nedenle küçük harf olmalıdır.


11
Bunun için gördüğüm en iyi tanım. Bağlantılı doktor taşınmış gibi görünüyor güncelleme cs.bilgi.edu.tr/pages/standards_project/…
robert

15
Nokta 2'yi alamıyorum. Asla nokta izlemeyen bir nesne türü örneği nedir? Tüm nesne türleri miras alır Objectve .equalsbunlar gibi bir yöntemi çağırabilirsiniz .
dogbane

6
Haklısın. Ve Boolean.TRUE, Boolean.FALSE, TimeUnit.MINUTES, String.CASE_INSENSITIVE_ORDER veya Collections.EMPTY_LIST gibi bazı Java sabitlerine bakıldığında da bunları takip edebilir ..
cbliard

5
@RomanIvanov Yine burada buldum: scribd.com/doc/15884743/Java-Coding-Style-by-Achut-Reddy Achut Reddy tarafından yazılmış, son güncelleme 30 Mayıs 2000
cbliard

1
2'nin amacının yalnızca karşılaştırılması amaçlanan sınıfların sabit olarak kabul edilmesini sağlamak olduğuna inanıyorum. Sınıfın 'kullanılması' amaçlanmamıştır. Ben SOME_CLASS.doStuff () gördüğümde her zaman küfür biliyorum. Sadece çirkin kodlama. Bununla ilgili tek sorun, yalnızca karşılaştırma amaçlı olan sabit bir nesnenin (String ortak örnek olan) genel durumundadır, ancak boş denetimleri önlemek için yoda stili kodlama kullanılır ve bu nedenle sabit üzerinde equals () çağrılır. Sanırım bunu 2'ye tek bir uyarı yapacağım.
Robin

44

Etkili java, 2. baskı,

Önceki kuralın tek istisnası, adları alt çizgi karakteriyle ayrılmış bir veya daha fazla büyük kelimeden (örneğin, VALUES veya NEGATIVE_INFINITY) oluşması gereken “sabit alanlar” ile ilgilidir. Sabit alan, değeri değişmez olan statik bir son alandır . Statik bir son alan ilkel bir tipe veya değişmez bir referans tipine (Madde 15) sahipse, sabit bir alandır. Örneğin, enum sabitleri sabit alanlardır. Statik bir son alan değiştirilebilir bir başvuru türüne sahipse, başvurulan nesne değiştirilemezse yine de sabit bir alan olabilir.

Özetle, sabit == statik final, artı bir referanssa (basit bir türe karşı) değişmezlik.

Slf4j kaydediciye bakarken, http://www.slf4j.org/api/org/slf4j/Logger.html

Değişmez. Öte yandan, JUL kaydedici değiştirilebilir. Log4j günlüğü de değiştirilebilir. Doğru olmak gerekirse, log4j veya JUL kullanıyorsanız, "logger" olmalı ve slf4j kullanıyorsanız, LOGGER olmalıdır.

Yukarıda bağlı slf4j javadocs sayfasının "LOGGER" değil, "logger" kullandıkları bir örneği olduğunu unutmayın.

Bunlar elbette sadece sözleşmelerdir, kurallar değildir. Slf4j kullanıyorsanız ve buna diğer çerçevelerden alışık olduğunuz için "logger" kullanmak istiyorsanız veya yazmak daha kolay veya okunabilirlik için devam ediyorsanız devam edin.


2
Bu gerekçeye dayanarak checkstyle'in basit tanımı uygun değil mi?
Robert

3
kontrol stilinin kurallarýný bilmiyorum. herhangi bir statik finalin büyük harf olması gerektiğinde ısrar ediyorsa, evet, bu yanlıştır.
Jeffrey Blattman

5
Logger Arayüz tam olarak nasıl değiştirilemez ? Sadece final class(benzeri Stringveya Integer) değişmezliği garanti edebilir. SLF4J'nin değişebilir bir uygulamasını bulamasanız bile Logger, kimse sizi kendiniz yazmanızı engelleyemez.
Costi Ciudatu

Çünkü arayüzdeki yöntemler doğal olarak mutasyona izin vermez. Değişebilir yan etkilere sahip olması için arayüzü uygulayabilmenize rağmen haklısınız.
Jeffrey Blattman

Kontrol stili kuralları okunabilirliği yansıtacak kadar OLGU DEĞİLDİR. Okunabilirlik bir stili değiştirerek elde edilemez, okunabilirlik bağlama göre duruma göre değişebilir. JDK koduna bakın, herhangi bir stil şablonunu izlemez ve profesyoneller tarafından yapılan, bir şey gösterir.
Daniel Hári

37

Google'ın bunu almasını seviyorum ( Google Java Stili )

Her sabit bir statik son alandır, ancak tüm statik son alanlar sabit değildir. Sabit durum seçmeden önce, alanın gerçekten bir sabit gibi olup olmadığını düşünün. Örneğin, söz konusu örneğin gözlemlenebilir durumundan herhangi biri değişebiliyorsa, neredeyse kesinlikle sabit değildir. Sadece nesneyi asla mutasyona uğratmaya niyetli olmak genellikle yeterli değildir.

Örnekler:

// Constants
static final int NUMBER = 5;
static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
static final Joiner COMMA_JOINER = Joiner.on(',');  // because Joiner is immutable
static final SomeMutableType[] EMPTY_ARRAY = {};
enum SomeEnum { ENUM_CONSTANT }

// Not constants
static String nonFinal = "non-final";
final String nonStatic = "non-static";
static final Set<String> mutableCollection = new HashSet<String>();
static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
static final Logger logger = Logger.getLogger(MyClass.getName());
static final String[] nonEmptyArray = {"these", "can", "change"};

6
Bence ilk cümle bunu özlü bir şekilde özetliyor: "Her sabit bir statik son alan, ancak tüm statik son alanlar sabit değildir." Mekanik düşünceyi kullanmak kolaydır ve her statik son alanı büyük harfle (ve şimdiye kadar bunu yapıyorum) ama bu dilin inceliğini kaçırmaktır.
ayahuasca

Bu alıntıya göre, alan bir sabit gibi "gerçekten hissediyorsa" kaybolur. Biz mühendisiz, psikiyatrist değiliz.
Jeffrey Blattman

"Bir sabit gibi geliyorsa ..." diyelim. Birinin duyguları gerçekten mühendislik alanına girmemelidir.
Jeffrey Blattman

Sonra private static final Logger logger = Logger.getLogger(Finalizer.class.getName());
Guava'nın

10

Kodlama standartlarınızı kontrol etmek için otomatik bir araç kullanıyorsanız ve söz konusu standartları ihlal ediyorsa, o zaman ya da standartlar sabitlenmelidir. Harici bir standart kullanıyorsanız, kodu düzeltin.

Sun Java'daki kural, genel statik sabitler için büyük harftir. Açıkçası bir kaydedici sabit değildir, ancak değişebilir bir şeyi temsil eder (aksi takdirde bir şeyin gerçekleşmesi umuduyla üzerinde yöntem çağırma yöntemi yoktur); sabit olmayan son alanlar için belirli bir standart yoktur.


10
Neden kaydedicinin sabit olmadığını söylüyorsunuz? Gerçekten sabit görünüyor. Günlüğe kaydetme, yöntemlerini çağırmanın bir yan etkisidir, ancak gözlemlenebilir durumunu değiştirmeyin. Bir şey mi kaçırdım?
KLE

API'yı kontrol edin. Bir ekleme / alma yöntemi vardır. Ama akıl yürütme zaten kusurlu. Günlüğe kaydetme gözlemlenebilir (aksi takdirde amaç nedir).
Tom Hawtin - tackline

3
Bir logger yerine bir StringBuilder olsaydı, belki de daha açık bir şekilde sabit olmazdı. Kaydediciler için bile Logger.setLevel () gibi yöntemler alıcıyı gözle görülür şekilde değiştirir. Genellikle büyük harf, dillerin sabit olarak davrandığı ve satır içinde olacağı sabitler içindir.
Pete Kirkham

5
Kaydedici bir nesneye referans olduğu için sabit değildir. Sabitler değiştirilemeyen değerlerdir. Nesne başvurusu kesindir (bu nedenle referans değiştirilemez, örneğin başka bir şeyle değiştirilemez veya null değerine ayarlanamaz) ancak nesnenin kendisi değişebilir.
Spoike

1
@JeffreyBlattman Tüm nihai referansların büyük harf olması gerektiğini kabul etmiyorum, ancak istediğiniz kodlama standartlarını benimsemekte özgürsünüz. 'Değişken nesne' ve 'değişebilir bir şeyi temsil eden nesne' arasındaki farkı kafa karıştırıcı bulduğunuz için üzgünüm; bunun bir örneği, kendisi değişmeyen ancak değişken bakiyeye erişmek için kullanılan arka hesap numaranız olabilir. Daha fazla ayrıntı için gösterici ve anlamlı arasındaki farkı veya değişmez bir şeyin değişebilirliği nasıl temsil edebileceğine dair Leibnitz monad'larına bir giriş arayın.
Pete Kirkham

7

Bunu google'da yaparsanız, bazı durumlarda kaydedicilerin statik final olarak tanımlanmadığını görebilirsiniz. Buna hızlı bir kopyala-yapıştır yapıştırın ve bu açıklayabilir.

Biz KAYIT'ı kullanmak bizim adlandırma kuralına tüm kodunda ve bu karşılık gelir (ve bizim checkstyle onunla mutlu).


Eclipse'deki sıkı adlandırma kuralından yararlanarak daha da ileri gidiyoruz. Şu kod şablonuyla yeni bir sınıf oluşturuyoruz:

    // private static final Logger LOGGER = Logger.getLogger(${enclosing_type}.class);

Başlangıçta ihtiyacımız olmadığı için kaydedici yorumlanır. Ama daha sonra ihtiyacımız olursa, sadece rahatsız ediyoruz.

Daha sonra kodda, bu günlükçünün mevcut olmasını bekleyen kod şablonlarını kullanıyoruz. Try-catch şablonuyla örnek:

    try {
      ${cursor} or some other template
    } catch (Exception t) {
      LOGGER.error("${methodName} ${method parameters}", t);
    }

Bunu kullanan birkaç şablonumuz daha var.

Sıkı kongre bizi daha üretken ve kod şablonları ile tutarlı olmasını sağlayacaktır .


5
Throwable'ı yakalamak, oturum açıp tekrar geri çevirmediğiniz sürece kötü bir uygulamadır. Hataları Unutmayın: OutOfMemeoryError, vb. Olay İstisnası, çok iş parçacıklı uygulamalarda kendiniz yakalamak ve işlemek için o kadar güvenli değildir.
m_vitaly

2
Eclipse sözdizimi: Logger.getLogger ($ {encing_type} .class);
dogbane

@fahdshariff Kesin sözdizimi için teşekkürler. Cevabımı güncelledim.
KLE

CheckStyle veya PMD'nin "katı kuralları" yardımcı oluyorsa, neden Guava ve JDK kaynaklarında HERHANGİ BİR ortak stil uygulanmaz? Örneğin, kaynaklarında gerektiğinde bol miktarda tam satır içi blok bulunur. Okunabilirlik bağlama bağlıdır, bu nedenle her şey için katı stil kuralları kullanmak içeriğe dayalı kararları yok eder, böylece okunabilirliği azaltır.
Daniel Hári

6

Şahsen büyük harflerle gerçekten büyük göründüğünü düşünüyorum. Buna doğrudan sınıf davranışı ile ilgili değil bir sınıf var Dahası, ben kullanarak büyük bir sorun görmüyorum loggeryerine LOGGER. Ama kesinlikle bilgiçlikçiyseniz, o zaman kullanın LOGGER.


4

PMD'nin bir yoruma saygı duyacağını unutmayın.

// NOPMD

içinde. Bu, PMD'nin hattı kontrollerinden atlamasına neden olur, bu da istediğiniz stili seçmenize izin verir.


6
Veya PMD kullanmayın, her zaman yanlış ve kodunuz mükemmel
IAdapter

1
Her seferinde bir çeki her zaman hariç tutmanız gerekiyorsa, kontrol mantıklı değildir.
keiki

Daha fazla anlaşamadı - ancak ... dışlama yorumunu bilmek yararlı
Fortyrunner

3

Genellikle sabitler büyük harflidir.

Ancak kaydediciler statik olmamalı, ancak slf4j cephesini kullanıyorsa, kapsayıcı sınıfın her "yeni" sini aramalıdır. Bu, özellikle web kaplarında bazı kötü sınıf yükleyici sorunlarını önler, ayrıca kaydedici çerçevesinin çağırma bağlamına bağlı olarak özel şeyler yapmasına izin verir.


2

Ben 'logger' yani küçük harf tercih ederim. Sebep, bunun bir sabit olması ya da sabit olmamasıdır (değişebilir ya da değişmez). Eğer bu muhakemeyi kullanırsak, kayıt çerçevesini değiştirirsek (veya çerçeve kaydedicilerin değişebilirliğini değiştirirse) değişkeni yeniden adlandırmamız gerekir.

Benim için başka nedenler daha önemli.

  1. Logger sınıftaki bir gölge nesnedir ve ana mantığı uygulamadığı için çok belirgin olmamalıdır. 'LOGGER' kullanırsak, kodda çok fazla dikkat çeken bir göz alıcıdır.

  2. Kaydediciler bazen örnek düzeyinde (yani statik olarak değil) bildirilir ve hatta bağımlılık olarak enjekte edilir. Kaydediciyi elde etme şeklimi değiştirmeye karar verirsem kodumu değiştirmek istemem. Kod kararlılığı wrt. bu (birçok durumda varsayımsal) değişim, küçük harfleri tercih etmemin bir diğer nedenidir.


1

Eğer kodlama standartlarınız - eğer varsa - büyük harf olmalı deyin evet.

Ben şu ya da bu şekilde katı bir neden görmüyorum. Bence bu tamamen kişisel beğenilerinize bağlıdır. şirket kodlama standartları.

BTW: "LOGGER" ;-) tercih ediyorum

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.