Neden "int i = 2147483647 + 1;" Tamam, ancak "bayt b = 127 + 1;" derlenebilir değil mi?


126

Neden int i = 2147483647 + 1;Tamam ama byte b = 127 + 1;derlenemez?


16
Benim de gerçek bir şüphem var: byteveri türü neden bu kadar acı verici ?!
BoltClock

9
kesinlikle byteimzasız yerine imzalanan bir tasarım hatasıdır .
tartışılmaz

4
@BoltClock Nasıl doğru kullanılacağını bilmediğin zaman sadece bir acı. stackoverflow.com/questions/397867/…
starblue

2
@starblue, Java bayt türünün uygulanabilir olduğu gerçek hayattan bir örnek var mı?
Thorbjørn Ravn Andersen

Bir bayt olarak belirtilen veri varsa, o zaman byte, örneğin parametrelerde, açıklık için bir Java kullanın . Bu durumda, intdeğer atayamamanız bazı hataları bile yakalayacaktır. Veya bytedizilerde yer kazanmak için kullanın . byteBir bayta sığan tek bir değer için kullanmam .
starblue

Yanıtlar:


172

Sabitler yüzden, ints olarak değerlendirilir 2147483647 + 1taşıyor ve size atanabilir olan yeni int verir intiken, 127 + 1aynı zamanda değerlendirilir intiçin eşittir 128ve bu kadar atanabilir değil byte.


10
Aslında bugün Java bulmacalarından bazılarını okudum , bunlarla ilgili bir bilmece de dahil ... Buraya bakın: javapuzzlers.com/java-puzzlers-sampler.pdf - puzzle 3
MByD

3
Sorun, intikili sayısal terfi nedeniyle tür , değer 127ise kırmızı ringa balığıdır.
starblue

Sabitlerin sonsuz hassasiyetle değerlendirilmesini ve ayrıca int i = 2147483647 + 1 üzerinde bir hata verilmesini tercih ederim;
Eduardo

@MByD: " while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte." dediğiniz gibi , bu 50 + 1'in değerlendirileceği byteve dolayısıyla atanabilir olduğu anlamına bytemı geliyor ?
Bhushan

1
@ 10101010 - tam olarak değil. bayta atanabilir, ancak önce (standarda göre) int olarak değerlendirilecektir.
MByD

35

Değişmez 127, int türünde bir değeri belirtir. 1 de öyle. Bu ikisinin toplamı 128 tamsayısıdır. İkinci durumda sorun, bunu bayt türündeki bir değişkene atıyor olmanızdır. İfadelerin gerçek değeri ile ilgisi yoktur. Java'nın zorlamaları (*) desteklememesi ile ilgisi var. Bir typecast eklemelisiniz

byte b = (byte)(127 + 1);

ve sonra derler.

(*) en azından String-to-integer, float-to-Time türünde değil, ... Java bir anlamda kayıpsız iseler zorlamaları destekler (Java bunu "genişletme" olarak adlandırır).

Ve hayır, "baskı" kelimesinin düzeltilmesi gerekmiyordu. Bunda çok bilinçli ve doğru seçildi. En yakın kaynaktan ele (Wikipedia): "Çoğu dilde, zorlama kelimesi ya derleme sırasında ya da çalıştırma sırasında örtük bir dönüşümü belirtmek için kullanılır ." ve "Bilgisayar biliminde, tür dönüştürme, tipleme ve zorlama, bir veri türündeki bir varlığı diğerine değiştirmenin örtük veya açık bir şekilde farklı yollarıdır."


Kod örneğiniz muhtemelen bayt b = (bayt) 127 + 1 olmalıdır; Bu, 'Maksimum bayt değerine 1 ekleyin', örneğiniz yalnızca 128'in int değerini bir bayt değerine dönüştürür.
NKCSS

6
@NKCSS - Haklı olduğunu sanmıyorum, bu - (byte)(127 + 1)128'i (tamsayı) bir bayta atarken, bu (byte)127 + 1127'yi bir bayta attı, sonra tekrar bir int'e, çünkü o 1 (int) ve sana eklendiğinden 128 (int) alın ve hata kalır.
MByD

6

@MByD'ye bir kanıt olarak:

Aşağıdaki kod derlenir:

byte c = (byte)(127 + 1);

Çünkü ifade (127 + 1), int ve kapsam dışı bytetipin ötesinde olmasına rağmen , sonuç dönüştürülür byte. Bu ifade üretir -128.


3

JLS3 # 5.2 Atama Dönüşümü

(değişken = ifade)

Ek olarak, ifade byte, short, char veya int türünde sabit bir ifadeyse (§15.28):

Değişkenin türü bayt, kısa veya karakter ise ve sabit ifadenin değeri değişkenin türünde gösterilebilirse, daraltıcı bir ilkel dönüşüm kullanılabilir.


Bu madde olmadan yazamazdık

byte x = 0;
char c = 0;

Ama bunu yapabilmeli miyiz? Ben öyle düşünmüyorum. İlkellerin din değiştirmesinde epeyce sihir vardır, çok dikkatli olunmalıdır. Yazma yolumdan çıkarım

byte x = (byte)0;

sorusuna gelince ... gerçekten yanlış bir şey görmüyorum byte x = 0ama yine de, ben bir C programcısıyım.
Grady Oyuncu

Belki char c = 0'a karşı bir argüman görebilirim, ama bayt x = 0 neden yanlış?
Michael Burge

Bir bayt değişkenine bir bayt 0 atadıklarını düşünerek, eğitimsiz gözler için yanıltıcıdır. Bu örnekte pek bir zararı yok, ancak genel olarak bayt / kısa / karakter üzerinde çalışmak, örtük dönüştürmeler nedeniyle çok kafa karıştırıcı olabilir. İnsanların düşündüğünden çok daha karmaşıklar. Kodumda olabildiğince fazla netlik istiyorum, birkaç tuş vuruşunu kurtarmak uğruna herhangi bir belirsizlik getirmeyin.
44'te reddedilemez

Uzunlamadan int'e daralan ilkel dönüşüm olduğunda, benzer bir kural geçerli midir, örneğin int i = 1 + 0L? Sadece alıntı yapılan metniniz bu durumu açıkça dışarıda bıraktığı için soruyorum.
Erwin Smout

@Erwin no, int i=0Lyasa dışıdır.
irreputable
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.