Sarmalayıcı sınıfı ve ilkel tür ne zaman kullanılır?


Yanıtlar:


70

Diğerleri, Collectionsnesneler gibi belirli yapıların ve nesnelerin ilkel emsallerinden (bellek ve kutulama) daha fazla ek yüke sahip olduğunu belirtmişlerdir.

Dikkate alınacak başka bir konu:

Durum veya işlevi belirtmek için Nesneleri bir yönteme / yapıcıya başlatmak nullveya nullparametreleri göndermek kullanışlı olabilir . Bu ilkellerle yapılamaz.

Birçok programcı bunu belirtmek için sayıları 0 (varsayılan) veya -1 olarak başlatır, ancak senaryoya bağlı olarak bu yanlış veya yanıltıcı olabilir.

Bu aynı zamanda, bir NullPointerExceptionşeyin yanlış kullanıldığı bir sahneyi de ayarlayacaktır , bu, sıradaki bazı rasgele hatalardan çok daha programcı dostudur.


15
"Nesneleri null olarak başlatmak kullanışlı olabilir". Kullanışlı olamaz çünkü bu yanlıştır, eğer alan isteğe bağlıysa, bunu açıkça belirtmelisiniz.
Eddie Jamsession

8
lol @EddieJamsession teşekkürler, bir daha asla null olarak başlatmayacağım. (pfffft)
pstanton

1
@EddieJamsession Gerçek değeri ayarlarken başarısızlığı göstermenin bir yolu olarak Objects null olarak başlatılırsa, bu sorunu yakalamak için başka ne önerirsiniz? Oh, şunu yazarken fark ettim: istisnalar. NullPointerException çok geneldir; neyin yanlış gittiğini belirtmek için çok özel özel istisnalar kullanmak daha iyi olacaktır. Güzel, bundan sonra bunu yapacağım ...
klaar

1
@EddieJamsession Konuyu okuduktan sonra, İsteğe Bağlı bir nesne kavramıyla karşılaştım. Sağ.
klaar

@klaar isteğe bağlı nesne nedir?
carloswm85

18

Genel olarak, herhangi bir nedenle bir nesneye ihtiyaç duymadığınız sürece (örneğin bir koleksiyon eklemek için) ilkel türleri kullanmalısınız . O zaman bile, sayısal performansı en üst düzeye çıkarmak istiyorsanız, bir nesne gerektirmeyen farklı bir yaklaşım düşünün. Bu, dokümantasyon tarafından tavsiye edilmektedir ve bu makale , otomatik kutunun nasıl büyük bir performans farkına neden olabileceğini göstermektedir.


3
performans isabeti o kadar iyi değil ki kod okunabilirliği / güvenilirliği arka planda kalmalı.
pstanton

3
İlk olarak, ilkelleri uygun şekilde kullanmak kodunuzu okunaksız hale getirmeyecektir. İkincisi, performans isabeti bazı durumlarda önemlidir. Asla olmadığını söylemek saçma.
Matthew Flaschen

1
@pstanton: Lütfen nasıl Integerdaha okunaklı olduğunu açıklayın int.
Stephen C

Pek çok durumda Tamsayı int'den daha okunaklı değildir ve bu durumlarda her zaman int kullanacağım veya belirli bir değişkenin HİÇBİR ZAMAN boş olmayacağını biliyorsam int kullanacağım çünkü int işaret ettiğiniz gibi biraz daha verimli. Bununla birlikte, çoğu durumda, başka bir programcının, bir nesne kullanıldığında bir değişkenin durumunu anlaması daha kolaydır, çünkü hazır olmadığını belirtmek için sıfır olarak başlatılabilir. Örneğin, benzersiz bir artan sayısal kimliği olan kaydedilmemiş bir veritabanı kaydınız varsa, bu kimlik geçerli bir kimlik atanmadan önce 0 mı, -1 mi yoksa boş mu olmalıdır? Bu durumda Nesneler daha iyidir.
pstanton

performansla ilgili olarak - özel durumlarda, performans vuruşu önemli olabilir, yani bu Nesnelerin çoğunu çok hızlı bir şekilde oluşturuyorsanız veya bunların çoğu belirli bir süre içinde birikirse. Bununla birlikte, iyi bir programcının bu özel durumları tespit etmesini veya buna göre değişiklik yapmasını beklerdim. Asla önemli olmadığını söylemedim, ancak genel olarak konuşursak, değil.
pstanton

12

Benim görüşüme göre, eğer sınıf üyelerim sarmalayıcı değişkenler ise, geliştirici dostu davranış olan varsayılan değerlere dayanmaz.

1.

class Person {
   int SSN ; // gets initialized to zero by default 
}

2.

class PersonBetter {
  Integer SSN; //gets initialized to null by default
}

İlk durumda, SSN değerini başlatılmamış halde tutamazsınız. Kullanmayı denemeden önce değerin ayarlanıp ayarlanmadığını kontrol etmemeniz canınızı yakabilir.

İkinci durumda, SSN'yi null ile başlatılmış halde tutabilirsiniz. Bu, NullPointerException'a yol açabilir, ancak SSN alanını başlatmadan kullanmaya çalıştığınızda, varsayılan değerleri (sıfır) bilmeden SSN olarak veritabanına eklemekten daha iyidir.


3
Oluşturucu kalıbı bunun üstesinden gelmek içindir. Bu senaryoda, örneği PersonBuilderalmak için "derleme" çağrısı yapmadan önce SSN ayarlanmadıysa bir istisna atar Person. Bence bu tür şeyler aşırı, ancak Java dilinin uygun kalıplar için teşvik ettiği şey bu.
Sandy Chapman

8

Gerekirse sadece sarıcı türlerini kullanırım.

Onları kullanırken, oldukları gerçeğinin yanı sıra fazla bir şey kazanmazsınız Objects.

Ayrıca, bellek kullanımındaki ek yükü ve boks / kutudan çıkarma için harcanan zamanı kaybedersiniz.


4
çok fazla kazanmayabilirsiniz, ama çok da kaybetmezsiniz. 1990'ların palmiye pilotunda koşmadığınız sürece.
pstanton

Nesne oldukları gerçeği, onlara basit bir ilkelden çok daha fazla bağlam ve kapsülleme sağlar. Dolayısıyla, bu ilkellerin ne anlama geldiğine ve nerede kullanıldıklarına bağlı olarak aslında çok şey kazanabilirsiniz.
aberrant80

4

Pratik olarak sarmalayıcı sınıfının kullanımının açıklanabileceği bir durumla karşılaştım.

Bir longtür değişkeni olan bir hizmet sınıfı oluşturdum

  1. Değişken longtürdeyse - başlatılmadığında 0'a ayarlanacaktır - bu, GUI'de görüntülendiğinde kullanıcı için kafa karıştırıcı olacaktır.
  2. Değişken Longtürdeyse - başlatılmadığında, olarak ayarlanacaktır null- bu boş değer GUI'de görünmeyecektir.

Bu Boolean, ilkel kullandığımızda değerlerin daha kafa karıştırıcı olabileceği durumlar için de geçerlidir boolean(çünkü varsayılan değer yanlıştır).


3

Koleksiyonlar, basit Java sarmalayıcı nesnelerinin tipik durumudur. Bununla birlikte, Sarmalayıcıya kodda (değer nesnesi) daha özel bir anlam vermeyi düşünebilirsiniz.

IMHO, kodun okunabilirliğine ve korunmasına indirgendiğinde, değer nesnelerini kullanmanın neredeyse her zaman bir faydası vardır. Belirli sorumluluklara sahip olduklarında nesnelerin içine basit veri yapılarını sarmak, genellikle kodu basitleştirir. Bu, Etki Alanına Dayalı Tasarımda çok önemli olan bir şeydir .

Elbette performans sorunu var, ancak performansı uygun verilerle ölçme ve sorunlu alana yönelik daha yönlendirilmiş eylemler yapma olanağına sahip olana kadar bunu görmezden gelme eğilimindeyim. Kodun anlaşılması kolaysa, performans sorununu anlamak da daha kolay olabilir.


3

Sayısal hesaplamaların hakim olduğu uygulamaların performansı , ilkellerin kullanımından büyük ölçüde faydalanabilir.

ilkel türler, biri == operatörünü kullanır, ancak sarmalayıcı için tercih edilen seçenek, equals () yöntemini çağırmaktır.

"İlkel tipler zararlı kabul edilir" çünkü "prosedürel semantiği başka türlü tek tip nesne yönelimli modelle karıştırırlar.

Birçok programcı bunu belirtmek için sayıları 0 (varsayılan) veya -1 olarak başlatır, ancak senaryoya bağlı olarak bu yanlış veya yanıltıcı olabilir.


1

Koleksiyonları kullanmak istiyorsanız, Wrapper sınıflarını kullanmanız gerekir .

İlkel türler, diziler için kullanılır. Ayrıca, sayacı veya boole koşulu gibi davranışı olmayan verileri temsil etmek için.

Otomatik kutudan bu yana, "ilkel veya sarmalayıcı ne zaman kullanılmalı" sınırı oldukça belirsiz hale geldi.

Ancak unutmayın, Sarmalayıcılar nesnelerdir, bu nedenle tüm lüks Java özelliklerini elde edersiniz. Örneğin, Tamsayı nesneleri oluşturmak için refleksyonu kullanabilirsiniz, ancak int değerlerini kullanamazsınız. Sarmalayıcı sınıfları da valueOf gibi yöntemlere sahiptir.


Koleksiyonlar dışında sarmalayıcı sınıfları kullanmamalı mıyım? Tamsayı i = new Integer (10) gibi sıradan bildirimler için kullanmaya ne dersiniz? Böyle yapmak iyi mi?
Gopi

otomatik kutulama Tamsayı i = 10 yapmanıza olanak sağlar;
Tom

1
Hayır, Sri. Benim bir nesne olmama şartınız yoksa, bunu yapma.
Matthew Flaschen

Otomatik kutulama, yukarıda belirtilen i'nin int i = 10 veya Tamsayı i = 10?
Gopi

3
int pi = new Tamsayı (10); İşler. Tamsayı oi = 10; İşler. int ni = boş; çalışmıyor. LHS, RHS'nin gerektirdiği şekilde dönüştürülür.
pstanton

0

Bir değer türü oluşturmak istiyorsanız. ProductSKU veya AirportCode gibi bir şey.

İlkel bir tür (örneklerimdeki dize) eşitliği tanımladığında, eşitliği geçersiz kılmak isteyeceksiniz.


5
dize ilkel değil
pstanton

2
temel nesne olarak bir dize içeren bir değer türünü sarmalamak için hala iyi nedenler vardır.
Chris Missal

cevabın hiç mantıklı değil. ne dediğinden emin değilim. Yorumunuza katılıyorum, ancak okunabilirliği artırıyorlarsa sarmalayıcı sınıfları iyi bir fikirdir.
pstanton

Değer türleri veya değer nesneleri yaratılmalı ve değişmez olmalıdır. Örneğin, yeni CountryCode ("USA") gibi bir "CountryCode" nesnesi oluşturmak ve ardından aynı şekilde başka bir nesne oluşturmak, daha sonra farklı olacakları bir anlam ifade etmeyecektir. Başlamak için sadece dizelerdir, ancak arkasında anlamlar vardır. Dizeleri kullanarak, onları değiştirebilirsiniz (daha fazla veri ekleyerek, vb.), Ancak artık eşit olmazlar. Açıklamaya çalıştığım şeyin daha iyi bir açıklaması için bu makaleye bakın :) Umarım bu mantıklıdır c2.com/cgi/wiki?ValueObject
Chris Missal

0

Java'daki ilkel değerler nesne değildir. Bu değerleri nesne olarak işlemek için, java.lang paketi her bir ilkel veri türü için bir sarmalayıcı sınıf sağlar.

Tüm Sarmalayıcı sınıfları nihaidir. Başlatılabilen tüm sarmalayıcı sınıflarının nesnesi değişmezdir, yani sarmalayıcı nesnesindeki değer değiştirilemez.

Ancak, void sınıfı bir sarmalayıcı sınıf olarak kabul edilir, ancak herhangi bir ilkel değeri sarmaz ve başlatılabilir değildir. Public constructor'ı yoktur, sadece void anahtar sözcüğünü temsil eden bir sınıf nesnesini belirtir.


0

İlkel Türler Ne Zaman Kullanılır?

  • Büyük miktarda hesaplama yaparken, ilkel türler her zaman daha hızlıdır - çok daha az ek yüke sahiptirler.
  • Değişkenin boş olmasını istemediğinizde.
  • Varsayılan değerin boş olmasını istemediğinizde.
  • Yöntemin bir değer döndürmesi gerekiyorsa

Sarmalayıcı Sınıfı Ne Zaman Kullanılmalı

  • Koleksiyonları veya Jenerikleri kullanırken - bu gereklidir
  • Bir türün MIN_SIZE veya MAX_SIZE olmasını istiyorsanız.
  • Değişkenin boş olmasını istediğinizde.
  • Varsayılan değerin null olmasını istediğinizde.
  • Bazen yöntem boş bir değer döndürebilir.

dan https://medium.com/@bpnorlander/java-understanding-primitive-types-and-wrapper-objects-a6798fb2afe9

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.