Java'da neden Sabit özellik yok?


140

Java sabitleri arkasındaki nedeni belirlemeye çalışıyordum Java öğrendim öğrendim finalanahtar kelime kullanarak sabit bildirmek için .

Sorum şu: Java neden bir Constant ( const) özelliği sunmadı . Birçok kişi C ++ 'dan geldiğini söylediğinden, C ++' da constanahtar kelimemiz var.

Lütfen düşüncelerinizi paylaşın.


2
Orada olan bir constanahtar kelime, ancak hiçbir altta yatan özelliği yoktur. Başlığınız ve etiketleriniz buna göre düzeltildi.
Lorne Marquis

Yanıtlar:


142

Ağır C ++ kodlamasından Java'ya her gittiğimde, Java'daki sabit doğruluk eksikliğine uyum sağlamak biraz zaman alıyor . constEğer bilmiyorsanız, C ++ 'da bu kullanım sadece sabit değişkenleri bildirmekten çok farklıdır. Temel olarak, bir const-pointer adı verilen özel bir işaretçi türünden erişildiğinde bir nesnenin değişmez olmasını sağlar Java'da, normalde bir sabit işaretçi döndürmek istediğim yerlerde, bunun yerine bir arabirim türüyle bir başvuru döndürürüm sadece yan etkileri olmamalı. Ne yazık ki, bu dil tarafından uygulanmıyor.

Wikipedia konuyla ilgili aşağıdaki bilgileri sunar:

İlginç bir şekilde, Java dil belirtimi, const'u ayrılmış bir anahtar kelime olarak (yani, değişken tanımlayıcı olarak kullanılamayan), ancak ona hiçbir anlam atamadığı kabul eder. Anahtar kelimenin rezervasyonunun, Java dilinin bir uzantısının C ++ tarzı const yöntemlerini ve const türüne işaretçi içermesine izin vermek için oluştuğu düşünülmektedir. Java'da const doğruluğunu uygulamak için Java Topluluğu Süreci'ndeki geliştirme isteği bileti 2005 yılında kapatıldı, bu da const doğruluğunun muhtemelen resmi Java spesifikasyonuna asla ulaşamayacağını ima ediyor.


10
Java finalda benzer.
reinierpost

62
Hayır değil. finalyöntemi örneğin C ++ constyöntemlerinden tamamen farklı çalışır .
dom0

7
@reinierpost Özellikler veya değişkenler üzerindekifinal anahtar kelime , bir özellik veya değişkenin yalnızca bir kez atanmasını sağlar . Yine de, örneğin, yan etkileri olan bir yöntem çağırarak bu nesnenin durumu değiştirilebilir. finalbir işaretçi yerine bir nesneye gönderme açısından C ++ tahsisini yığınlamak için biraz similair, ama hepsi bu. Bu, dom0'ın zaten söylediklerine ek olarak elbette.
Tim

9
finalJava'da constdeğer türleri için C ++ gibi çalışıyor , ancak daha çok T&referans türleri için C ++ sabit olmayan gibi görünüyor
Mark K Cowan

1
final şizofrenik bir anahtar kelimedir. Yeniden atamayı önlese de, değişkenleri kapaklara maruz bırakmak için de kullanılır. Yeniden atamayı önlemek isteyebilirim, ancak bu değişkenleri ortaya çıkarmak istemiyorum, ancak bunu yapmanın bir yolu yok. Bence oldukça zayıf düşünülmüş bir dil özelliği.
David Bradley

82

Ne anlama constgeliyor?
Bir "const" anahtar kelimesinin anlambiliminin farklı insanlar için farklı şeyler ifade ettiğini fark edin:

  • salt okunur başvuru - Java finalsemantiği - başvuru değişkeninin kendisi başka bir örneği (bellek konumu) işaret edecek şekilde yeniden atanamaz, ancak örneğin kendisi değiştirilebilir
  • yalnızca okunabilir referans - C constişaretçisi / referans anlambilimi - bu başvurunun örneği değiştirmek için kullanılamayacağı anlamına gelir (örneğin, örnek değişkenlere atayamaz, değiştirilebilir yöntemleri çağıramaz) - yalnızca referans değişkenini etkiler, bu nedenle aynı örnek, örneği değiştirebilir
  • değişmez nesne - örneğin kendisinin değiştirilemeyeceği anlamına gelir - örneğe uygulanır, bu nedenle const olmayan referanslara izin verilmez veya örneği değiştirmek için kullanılamaz
  • yukarıdakilerin bir kombinasyonu ?
  • diğerleri ?

Neden veya Nedenconst
İkinci Değil , gerçekten "pro" ve "con" argümanlarından bazılarını incelemek istiyorsanız, bu geliştirme isteği (RFE) "hatası" altındaki tartışmaya bakın. Bu RFE, "yalnızca okunabilir referans" türü "const" özelliği ister. 1999'da açılan ve daha sonra 2005'te Sun tarafından kapatılan / reddedilen "const" konusu şiddetle tartışıldı:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4211070

Her iki tarafta da çok iyi argümanlar olsa da, çoğu zaman alıntılanan (ancak zorunlu olarak zorlayıcı veya kesin olmayan) nedenler constşunlardır:

  • kötüye kullanılabilen ve / veya kötüye kullanılabilen kafa karıştırıcı semantiklere sahip olabilir (bkz. yukarıda ne anlama constgeliyor )
  • başka türlü mevcut olabilir (örneğin değişmez bir arabirim kullanarak değişmez bir sınıf tasarlamak)
  • özellik sürünmesi olabilir ve nesnelerin değere göre aktarılması için destek gibi diğer anlamsal değişikliklere ihtiyaç vardır

Bunların iyi veya kötü nedenler olup olmadığı konusunda kimse beni tartışmaya çalışmadan önce, bunların nedenlerim olmadığını unutmayın . Onlar sadece RFE tartışmasını gözden kaçırmak için neden bazı nedenleri "özü". Onlarla kendim aynı fikirde değilim - sadece bazı insanların (ben değil) neden bir constanahtar kelimenin iyi bir fikir olmadığını düşünmeye çalışıyorum. Şahsen, dile daha açık bir şekilde tanıtılmak için daha fazla "const" anlambilimi isterdim.


2
Cevabınızın sadece ikinci kısmı için +1. Birçok anahtar kelimenin önemsiz anlambilimi vardır. Mı volatilebasit anlamak çok? Yoksa final? Meh.
einpoklum

OTOH, Java, önemsiz olmayan özelliklerden mümkün olduğunca azını kullanmak üzere tasarlanmıştır. Ve ben bu hedefe ulaştıklarını söylemiyorum (ya da Java bu hedeften uzaklaşmadı). Fakat bu nedenle dışlamak hala haklıdır. Başka karmaşık şeylerin olması, daha fazlasını tanıtmamak için daha fazla nedendir (veya D dili ile sonuçlanırsınız).
Maarten Bodewes

7

const C ++ 'da bir değerin sabit olduğu anlamına gelmez.

const C ++ 'da bir sözleşmenin müşterisinin değerini değiştirmemeyi taahhüt ettiği anlamına gelir.

İş constparçacığı tabanlı eşzamanlılığı destekleyen bir ortamdaysanız , bir ifadenin değerinin değişip değişmeyeceği daha belirgin hale gelir.

Java başından beri iş parçacığı ve kilit eşzamanlılığını desteklemek için tasarlandığından, semantiğe sahip olmak için terimi aşırı yükleyerek karışıklığa neden olmadı final.

Örneğin:

#include <iostream>

int main ()
{
    volatile const int x = 42;

    std::cout << x << std::endl;

    *const_cast<int*>(&x) = 7;

    std::cout << x << std::endl;

    return 0;
}

çıkışlar 42 sonra 7.

Sabit olmayan bir takma ad oluşturuldukça xişaretli olmasına rağmen const, xsabit değildir. Her derleyici volatilebu davranış için gerekli değildir (her derleyicinin sabiti satır içine almasına izin verilir)

Daha karmaşık sistemlerde const_cast, kullanmadan const / const olmayan takma adlar alırsınız , bu nedenle const'un bir şeyin değişmeyeceği anlamına gelme alışkanlığına girmek gittikçe tehlikeli hale gelir. constsadece kodunuzun bir cast olmadan onu değiştiremeyeceği, değerin sabit olduğu anlamına gelmez.


3
const int x = 42; - x sabittir

2
@Neil Hem const hem de const olmayan işaretçiler tarafından takma bir nesneniz veya değişkeniniz varsa, const diğer adının değeri const olmayan diğer ad tarafından değiştirilebilir. Bu nedenle constbir değerin sabit olduğu anlamına gelmez. Bu, bir değerin istemcisinin onu değiştirmemesi için kısıtlandığı anlamına gelir. Örneğinizde takma ad yok, bu nedenle tüm kullanıcılar aynı kısıtlama altında. Genel olarak durum böyle değil. constdeğeri değil istemcileri etkiler - değiştiremeyeceğinizi, değişmeyeceğini söyler.
Pete Kirkham

1
İnş-doğruluğu programcı ile ilgili ne olmalıdır , değil ne yapabiliriz . Bence hepiniz bu noktaya değindiniz. Nedensel okuyucunun ilgisini çekebilecek birkaç sent eklemek istedim: Java'daki sabitleri taklit etmek için immutable interfaceve benzeri gibi tasarım kalıpları immutable object(döküm ve yansıma ile yenilebilir). "True" const, SealedObject ile yapılabilir , ne yazık ki nesnemizin kullanım durumunu yok eder.
Martin Andersson

6
Programınızın sonucunun tanımsız olduğuna dikkat edilmelidir. const_cast, const değişkenlerini değiştirmek için orada değildir, const değişkenlerini const doğru olmayan API'lara geçirmek, ancak değeri değiştirmemek için vardır. Bence bir şeyin değişmeyeceğini düşünme alışkanlığı iyi bir şeydir, çünkü eğer değişirlerse, programınız kullanılan derleyiciye bağlı olarak herhangi bir zamanda kırılabilecek kesmek içeriyor demektir.
Cygon

1
Doğuştan sabite bir değerin değiştirilmesi tanımlanmamış bir davranıştır. Diskiniz zaten biçimlendirilmiş olabilir.
Zhe Yang

5

Bu biraz eski bir soru, ama ben bu konu bugün konuşma geldi çünkü ben zaten benim 2 sent katkıda olacağını düşündüm.

Bu tam olarak neden const yok diye cevap vermiyor ? ama sınıflarınızı nasıl değişmez kılarsınız. (Maalesef kabul edilen yanıta yorum yapmak için henüz yeterli itibarım yok)

Bir cisim üzerindeki değişmezliği garanti etmenin yolu, sınıflarınızı değişmez olacak şekilde daha dikkatli bir şekilde tasarlamaktır. Bu değişebilir bir sınıftan biraz daha fazla bakım gerektirir.

Bu Josh Bloch'un Etkili Java Öğesi 15 - Değişebilirliği En Aza İndir'e geri dönüyor . Kitabı okumadıysanız, bir kopyasını alın ve birkaç kez tekrarlayın, çünkü mecazi "java oyununuzu" garanti altına alacaktır .

15. maddede Bloch, nesnenin durumunu sağlamak için sınıfların değiştirilebilirliğini sınırlamanız gerektiğini önerir.

Kitabı doğrudan alıntılamak için:

Değişmez bir sınıf, basitçe örnekleri değiştirilemeyen bir sınıftır. Her örnekte yer alan tüm bilgiler, oluşturulduğunda ve nesnenin ömrü boyunca sabitlendiğinde sağlanır. Java platformu kitaplıkları, String, kutulu ilkel sınıflar ve BigInteger ve BigDecimal dahil olmak üzere birçok değişmez sınıf içerir. Bunun pek çok iyi nedeni vardır: Değişmez sınıfları tasarlamak, uygulamak ve kullanmak değiştirilebilir sınıflardan daha kolaydır. Hataya daha az eğilimlidirler ve daha güvenlidirler.

Bloch daha sonra 5 basit kuralı izleyerek sınıflarınızı nasıl değişmez hale getireceğinizi açıklar:

  1. Nesnenin durumunu değiştiren herhangi bir yöntem (örneğin ayarlayıcılar, diğer bir deyişle mutasyoncular ) sunmayın
  2. Sınıfın genişletilemediğinden emin olun (bu, sınıfın kendisini şu şekilde bildirmek anlamına gelir final).
  3. Tüm alanları yapın final.
  4. Tüm alanları yapın private.
  5. Değişebilir bileşenlere özel erişim sağlayın. (nesnelerin savunma kopyalarını oluşturarak)

Daha fazla bilgi için kitabın bir kopyasını almanızı şiddetle tavsiye ederim.


3
C ++ 'da const tam ölçekli değişmezlikten çok daha esnektir. Bir anlamda, 'const' 'bu bağlamda değişmez' olarak görülebilir. Örnek: Değişmez olmayan bir sınıfım var, ancak bazı ortak API'lar aracılığıyla değiştirilmediğinden emin olmak istiyorum. Gunslinger47 tarafından önerildiği gibi bir arayüz yapmak (ve bu ortak API için geri döndürmek) Java'da aynı şeyi başarıyor, ancak çocuk - çirkin (ve böylece - Java geliştiricilerinin çoğu tarafından göz ardı ediliyor ve gereksiz gereksiz karışıklığa yol açıyor). .
No-Hatalar Hare

3

C ++ semantiği constJava'dan çok farklıdır final. Tasarımcılar kullansaydı, constgereksiz yere kafa karıştırıcı olurdu.

Aslında constayrılmış bir kelimedir tasarımcılar uygulanması için fikirler vardı önerir const, ancak buna karşı karar beri var; bkz Bu kapalı hata . Belirtilen nedenler arasında C ++ stili için destek eklenmesi constuyumluluk sorunlarına neden olacaktır.


-1

Java'da "const" değişkenleri oluşturmanın bir yolu vardır, ancak yalnızca belirli sınıflar için. Sadece final özelliklerine sahip bir sınıf tanımlayın ve alt sınıfı sınıflandırın. Sonra "const" kullanmak istediğiniz temel sınıfı kullanın. Benzer şekilde, "const" yöntemlerini kullanmanız gerekiyorsa, bunları temel sınıfa ekleyin. Derleyici, temel sınıfın son yöntemleri olduğunu düşündüğü şeyi değiştirmenize izin vermeyecektir, ancak alt sınıftaki yöntemleri okuyacak ve çağıracaktır.


Buna bir örnek verebilir misiniz lütfen?
NO_NAME

sınıf MYString GetString {private final String aaaa; public String getString (); } class MutableString, GetString {private String aaaa2; public String getString (); public String setString ()}
user1122069

-2

Sabitleri tanımlamanın iki yolu olacaktır - constve static finaltam olarak aynı anlambilimle. Ayrıca static finaldavranışıconst


@Bozho, Const'tan daha iyi davranışlar söyledin, bu nasıl? herhangi bir örnek paylaşabilir misiniz
gmhk

değişken static(belirli bir örneğe ait değil) ve final- değiştirilemez.
Bozho

-2

Const'a benzer bir şey yaratmak için statik final kullanabilirsiniz, bunu geçmişte kullandım.

protected static final int cOTHER = 0;
protected static final int cRPM = 1;
protected static final int cSPEED = 2;
protected static final int cTPS = 3;
protected int DataItemEnum = 0;

public static final int INVALID_PIN = -1;
public static final int LED_PIN = 0;

Söylentiye dayalı optimizasyon için indirildi çünkü bunun etkisiz bir strateji olduğuna dair bir söylenti duydum.
afarley

Söylentiyi cevaptan çıkardım. hala const stil kodu oluşturmak için statik son int kullanabilirsiniz.
hamish

Tamam, düşüşümü kaldırdım. Belki diğer aşağı oylardan bazıları switch ifadesi ile ilgilidir (örneğinizin geri kalanıyla ne ilgisi var?)
afarley

switch deyiminde cRPM'yi bir const gibi kullandım. yukarıdakileri göz önünde bulundurarak oldukça doğru. yani evet anahtarı kaldırdım.
hamish
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.