Burada (int) için bir tamsayı hazırlamam için neden ihtiyacım olduğu hakkında bir fikriniz var mı?


122

Aşağıdaki örnekte

int i = -128;
Integer i2 = (Integer) i; // compiles

Integer i3 = (Integer) -128; /*** Doesn't compile ***/

Integer i4 = (Integer) (int) -128; // compiles
Integer i4 = -128; // compiles
Integer i5 = (int) -128; // compiles
Integer i6 = (Integer) (-128); // compiles
Integer i7 = (Integer) 0-128; // compiles

Ben yayın yapılamıyor -128ile (Integer)ancak yayınlayabileceğim (int) -128.

Hep düşündüm -128oldu inttipine ve onu döküm (int)gereksiz olmalıdır.

İle hat üzerinde hata i3DİR

cannot find symbol variable Integer

Bunu Java 6 güncelleme 29 ve Java 7 güncelleme 1 ile denedim.

DÜZENLEME: +128yerine ile aynı davranışı elde edersiniz -128. Tekli ve ikili operatörler arasında bir kafa karışıklığı gibi görünüyor.


5
derleyiciniz nedir? Integer i = -128;bu yine de derlenmelidir.
bestsss

tuhaf, Integer i3 = (Integer) (-128);yine de uyuyor.
Eng.Fouad

2
@ Eng.Fouad, Peter, tekli semboller (+ -) sağdan sola ilişkilendirilebilir ve artı, eksi soldan sağa. -128'in etkisi +128 ile aynıdır ve önüne 0 koymak sabitlenmelidir, yani 0-128 veya 0 + 128. (atm test edemiyorum ama eminim öyle olacak)
bestsss

İyi soru! Şahsen, tekli / ikili operatörlerin çözümlenmesi için ve bir atama bir ifade olarak ele alındığında bir JLS referansı görmek istiyorum. Aksi takdirde, diğer derleyicilerin bunu bir hata olarak görmemesi mümkün olabilir!
Bringer128

1
Ayrıca FYI IDE'mde aldığım hata Expression expectednerede Integerolduğu.
Bringer128

Yanıtlar:


151

Derleyici çıkarmak çalışır 128dan (Integer)yerine döküm -128için Integer. ()Düzeltmek için ekleyin

Integer i3 = (Integer) -128; // doesn't compile
Integer i3 = (Integer) (-128); // compiles

Yorumlarda BoltClock'a göre, oyuncu kadrosu intamaçlandığı gibi çalışıyor, çünkü ayrılmış bir kelime ve bu nedenle bir tanımlayıcı olarak yorumlanamıyor, bu bana mantıklı geliyor.

Ve Bringer128 JLS Referans bulundu 15.16 .

 CastExpression:
    (PrimitiveType Dims opt ) UnaryExpression
    (ReferenceType) UnaryExpressionNotPlusMinus

Gördüğünüz gibi, ilkel bir türe UnaryExpressionçevrim herhangi birini gerektirirken , bir referans türüne çevrim bir UnaryExpressionNotPlusMinus. Bunlar, JLS 15.15'te CastExpression'dan hemen önce tanımlanmıştır .


31
Sanırım intJava'da bir anahtar kelime olduğu için, ama Integerdeğil. Yana intbir anahtar kelimedir, bunun bir typecast olabilmesi için geriye kalan tek olasılık bırakarak bir değişken veya bir sınıf için bir tanımlayıcı olarak kullanamazsınız. Bu onu açıklar.
BoltClock

@BoltClock Yorumunuzu cevaba dahil etti.
Jens Schauder

3
Bunu daha da mükemmel bir cevap yapmak için, bağlantımı JLS'ye eklemek ister misiniz?
Bringer128

3
Bu konudaki ilginç (bana göre) bir kırışıklık, "ikili çıkarma operatörüne bir işlenen olarak parantezli ifade" ve "döküm operatörü olarak doğru operandın bulunduğu yerde bir belirsizliğe sahip olan C #'daki benzer problemi nasıl çözdüğümüzdür. cast tek terimli eksi bir ifadedir ". Amgiguity'yi çözme konusunda akıllı davranmaya çalışmak için kullandığımız buluşsal yöntemlerin ayrıntılı bir açıklaması için C # belirtiminin 7.7.6 bölümüne bakın.
Eric Lippert

1
@BillK Bunu neden söylüyorsun? C # özelliği, 7.7.6 bölümünde operatör aşırı yüklemesine atıfta bulunmaz, bu nedenle onlar için bir sorun değildi.
Bringer128

48

JLS referansını buldum. 15.16 .

 CastExpression:
    (PrimitiveType Dims opt ) UnaryExpression
    (ReferenceType) UnaryExpressionNotPlusMinus

Gördüğünüz gibi, ilkel bir türe UnaryExpressionçevrim herhangi birini gerektirirken , bir referans türüne çevrim bir UnaryExpressionNotPlusMinus. Bunlar, JLS 15.15'te CastExpression'dan hemen önce tanımlanmıştır .

Ya ilkel bir türe değiştirmelisiniz:

... (int) -128;

Ya da alıcının sağındaki ifadeyi artı-eksi olmayan tek terimli bir ifadeye dönüştürebilirsiniz:

... (Integer) (-128);  // Either
... (Integer) 0 - 128; // Or

12

Derleyici -, iki argümanlı eksi operatörü olarak yorumluyor , yani adı verilen başka bir sayıdan 128'i çıkarmaya çalışıyor Integer, ancak kapsamda böyle bir değişken yok.

Bu derler:

Integer i3 = (Integer) (-128)

Neden (int)bir fark yarattığına dair bir yorum ekleyebilirsiniz .
Peter Lawrey

1
Otomatik kutudan dolayı, değil mi?
Brian Roach

9

Bunun sözdizimi ayrıştırmasıyla ilgisi olabilir. Dikkat edin

Integer i4 = (Integer) (-128); 

gayet iyi çalışıyor.

Genel olarak, Tamsayı sınıfına dönüştürmemelisiniz. Bu, otomatik kutulama adı verilen bir şeyi içerir ve kodunuzda bazı ince hatalara neden olabilir. İstediğinizi yapmanın tercih edilen yöntemi şudur:

Integer i6 = Integer.valueOf(-128)

1
Tamsayıya çevrim değeri, tam olarak sentetik şekerdir.
bestsss

4
evet, ancak bazen sentetik şeker ince şekillerde başarısız olur. Otomatik kutulama nedeniyle büyük uygulamalarda boş işaretçi istisnalarını bulmakta zorlandım. Gelecekte baş ağrılarından kurtulmak için otomatik kutuyu hata olarak ele almaya kadar gittik. Büyü güzeldir ama başarısız olduğunda kafalar ağrır. Açıkça konuşmanın ve baş ağrılarından kurtulmanın daha iyi olduğunu düşünüyorum.
Krystian Cybulski

NPE, kutudan çıkan b1tch'dir, doğru. for (int i in Collection<Integer>)NPE b / c gibi esp vakaları kesinlikle beklenmedik bir konumdadır. Önbellek aralığı küçük olduğu için (her ne kadar XX seçeneği ile artırılsa da) Tamsayı w / autoboxing kullanmıyorum ama aynı şeyi yapmak için IntegerProvider (1.1'den beri) adlı bir sınıfa sahibim. Harita Kullanımı (java.util'den herhangi biri) Tamsayı-> Her şey, önemsiz durumlar için kullanılmadığı ve hemen hemen her zaman daha iyi bir çözüm olmadığı sürece, genellikle bir performans vuruşu olur.
bestsss

İnt türünün Tamsayıya çevrilmesi, belki de yığın taşması dışında hiçbir zaman hataya neden olmaz. Tersi yine de doğru değil.
Ingo

@MattBall, tam olarak anlamıyorum, sentetik şeker yaygın olarak kullanılıyor: eggcorns.lascribe.net/forum/viewtopic.php?id=4400 ve sentetik sesler benim için daha iyi.
bestsss

9

Olarak ayrıştırıyor Integer <minus operator> 128ve değişkeni bulamıyor Integer. -128Parantez içine almanız gerekir :

Integer i3 = (Integer) (-128);  // compiles

Diğer tüm yanıtlara +1 verdim çünkü hepsi de doğru :)
Bohem

7
Integer i3 = (Integer) (-128);

Sorun şu ki -, derleyici onu bir operatör olarak görüyor.


6

Satır 3, parantez içindeki ifadeden 128'i çıkarmaya çalıştığınız gibi yorumlanır ve parantez içindeki ifade, int türünde bir ifade değildir ('-' bir '-' operatörü olarak ele alınır). İfadeyi şu şekilde değiştirirseniz:

Integer i3 = (Integer) (-128);

daha sonra derleyici '-' nin negatif bir tamsayıyı gösteren tekli eksi olduğunu anlayacaktır.


3

C # derleyicisi aynı davranışa sahiptir. Yine de neden derlenemediğine dair daha iyi bir ipucu verir:

Negatif bir değer atmak için, değeri parantez içine almanız gerekir

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.