1. Tip Tahmini

Java'da tip tahmini

İlkel tür değişkenleri (tür hariç boolean), çeşitli sayı türlerini depolamak için kullanılır. Değişkenlerin türleri hiç değişmese de, bir türden diğerine dönüştürebileceğiniz bir yer var. Ve orası görev yeridir .

Farklı tipteki değişkenler birbirine atanabilir. Bunu yaptığınızda, bir türdeki değişkenin değeri başka bir türdeki değere dönüştürülür ve ikinci değişkene atanır. Bu bağlamda, iki tür dönüştürme tanımlayabiliriz: genişletme ve daraltma.

Genişletme, bir değeri küçük bir sepetten büyük bir sepete taşımak gibidir: bu işlem kesintisiz ve ağrısızdır. Bir değeri büyük bir sepetten küçük bir sepete taşıdığınızda daralma meydana gelir: yeterli alan olmayabilir ve bir şeyi atmak zorunda kalırsınız.

Sepet boyutuna göre sıralanmış türler şunlardır:

Java 2'de tip tahmini


2. Genişletme türü dönüşümleri

Genellikle bir sayısal türdeki değişkeni başka bir sayısal türdeki değişkene atamak gerekir. Bunu nasıl yaptın?

Java'nın 4 tamsayı türü vardır:

Tip Boyut
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

Daha küçük sepetlerde saklanan değişken, her zaman daha büyük sepetlerde saklanan değişkenlere atanabilir.

intve değişkenler kolayca shortdeğişkenlere byteatanabilir long. shortve bytedeğişkenler değişkenlere atanabilir int. Ve bytedeğişkenler değişkenlere atanabilir short.

Örnekler:

kod Tanım
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Bu kod gayet iyi derlenecek.

Daha küçük bir türden daha büyük bir türe böyle bir dönüştürme, genişleyen tür dönüştürme olarak adlandırılır .

Peki ya gerçek sayılar?

Onlarla her şey aynı — boyut önemlidir:

Tip Boyut
float 4 bytes
double 8 bytes

floatdoubledeğişkenler sorunsuz bir şekilde değişkenlere atanabilir . Ancak tamsayı türleri ile işler daha ilginç.

Herhangi bir tamsayı değişkenini bir değişkene atayabilirsiniz float. long8 bayt uzunluğundaki tür bile . floatVe bir değişkene - herhangi bir tamsayı değişkeni veya değişken - istediğinizi atayabilirsiniz double:

kod Not
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Gerçek bir türe dönüştürmenin, yeterli anlamlı basamak olmaması nedeniyle kesinlik kaybına neden olabileceğini unutmayın.

Tam sayılardan kayan noktalı sayılara dönüştürürken, sayıların alt sıralı kısımları atılabilir. Ancak kesirli sayıların yaklaşık değerleri sakladığı anlaşıldığından, bu tür atama işlemlerine izin verilir.


3. Daralan tür dönüşümleri

Peki ya diğer olasılıklar? longBir değişkene bir değer atamanız gerekirse ne olur int?

Bir değişkeni bir sepet olarak hayal edin. Çeşitli boyutlarda sepetlerimiz var: 1, 2, 4 ve 8 bayt. Elmaları daha küçük bir sepetten daha büyük bir sepete aktarmak sorun değil. Ancak daha büyük bir sepetten daha küçük bir sepete geçerken elmaların bir kısmı kaybolabilir.

Bu dönüşüm - daha büyük bir türden daha küçük bir türe - daraltıcı tür dönüşümü olarak adlandırılır . Bunun gibi bir atama işlemi gerçekleştirirken, sayının bir kısmı yeni değişkene sığmayabilir ve bu nedenle atılabilir.

Bir türü daraltırken, derleyiciye hata yapmadığımızı, sayının bir kısmını kasıtlı olarak attığımızı açıkça söylemeliyiz. Bunun için typecast operatörü kullanılır. Parantez içinde bir tür adıdır .

Bu gibi durumlarda, Java derleyicisi , programcının typecast operatörünü belirtmesini gerektirir. Genel olarak, şöyle görünür:

(type) expression

Örnekler:

kod Tanım
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Typecast operatörünün her defasında açıkça belirtilmesi gerekir

İşte aeşittir 1ve belki de yazım işleci aşırıya kaçmış gibi görünüyor. Ama ya adaha büyük olsaydı?

kod Tanım
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

Bir milyon a'ya longve bir int. Ancak bir değişkene bir milyon atarken short, ilk iki bayt atılır ve yalnızca son iki bayt korunur. Ve a'ya atama yaparken bytegeriye kalan tek şey son bayttır.

Sayılar hafızada nasıl düzenlenir:

Tip İkili gösterim Ondalık gösterim
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

chartip

A char, a gibi short, iki bayt yer kaplar, ancak birini diğerine dönüştürmek için her zaman bir yazım işleci kullanmanız gerekir. Buradaki sorun, tipin imzalı olması ve -den shortdeğerler içermesi , ancak tipin unsigned olması ve -den -den değerler içermesidir .-32,768+32,767char065,535

Negatif sayılar a'da saklanamaz char, ancak a'da saklanabilirler short. Ve a, short'den büyük sayıları saklayamaz 32,767, ancak bu tür sayılar a'da saklanabilir char.


4. Bir ifade türü

Aynı ifadede farklı türde değişkenler kullanılırsa ne olur? Mantıken, önce ortak bir türe dönüştürülmeleri gerektiğini anlıyoruz. Fakat hangisi?

Tabii ki daha büyüğüne.

Java her zaman daha büyük türe dönüştürür. Kabaca söylemek gerekirse, önce türlerden biri genişletilir ve ancak bundan sonra aynı türdeki değerler kullanılarak işlem gerçekleştirilir.

Bir ifadede an intve a longvarsa, the'nin değeri inta'ya dönüştürülür longve ancak o zaman işlem devam eder:

kod Tanım
int a = 1;
long b = 2;
long c = a + b;
aa'ya genişletilecek longve ardından ekleme gerçekleşecek.

Kayan nokta sayıları

Bir ifadede bir tamsayı ve bir kayan noktalı sayı ( floatveya ) varsa, tamsayı bir kayan noktalı sayıya ( veya ) doubledönüştürülür ve ancak o zaman işlem gerçekleştirilir.floatdouble

İşlem a floatve a'yı içeriyorsa double, floata'ya dönüştürülecektir double. Bu aslında bekleniyor.

Sürpriz

, ve türleri , birbirleriyle etkileşime girdiklerinde her bytezaman dönüştürülür . Türün standart tamsayı türü olarak kabul edilmesinin iyi bir nedeni vardır .shortcharintint

bytea ile a'yı çarparsanız short, an elde edersiniz int. bytea ile a'yı çarparsanız byte, an elde edersiniz int. bytea ve a ekleseniz bile byte, bir elde edersiniz int.

Bunun birkaç nedeni var. Örnekler:

kod Tanım
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 12013,200türün maksimum değerinden biraz daha büyük olan byte:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120is 230, bu da türün maksimum değerinden biraz daha büyüktür byte:127

Genel olarak, 8 bitlik (1 bayt) bir sayıyı 8 bitlik (1 bayt) bir sayı ile çarptığımızda, 16 bitlik (2 bayt) yer kaplayan bir sayı elde ederiz.

Sonuç olarak, daha küçük tamsayı türlerine sahip tüm işlemler inther zaman anında s'ye dönüştürülür int. Bu da, hesaplamanın sonucunu a'dan küçük bir tür değişkeninde depolamak istiyorsanız int, o zaman tip belirleme operatörünü her zaman açıkça belirtmeniz gerekeceği anlamına gelir.

Örnekler:

kod Tanım
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
ifade byte * bytebir olacakint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
ifade byte + bytebir olacakint
byte a = 1;
byte b = (byte) (a + 1);
İfade byte + intbir olacaktır. int
Gerçek olan bir int.

5. Önemli bir nüans

Typecast operatörü oldukça yüksek bir önceliğe sahiptir.

Bunun anlamı, örneğin bir ifade toplama ve bir tip belirleme işleci içeriyorsa, tip belirlemenin toplamadan önce gerçekleştirileceğidir.

Örnek:

kod Tanım
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
aTypecast operatörü, yalnızca zaten bir olan değişkene uygulanacaktır byte. Bu kod derlenmeyecek.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Bu doğru yol.

İfadenin yalnızca bir bileşenini değil, tüm ifadeyi belirli bir türe dönüştürmek istiyorsanız, tüm ifadeyi parantez içine alın ve typecast operatörünü öne koyun.