Java'da ilkel türleri dönüştürme. Tür dönüştürme ve döküm. İfadelerde otomatik tür tanıtımı

  • 29.07.2019

Çoğu zaman, dizeleri int veya boolean gibi diğer türlerin değerlerine veya tam tersi şekilde dönüştürmeye ihtiyaç vardır. Kural olarak, dizeyi dönüştürme sorumluluğu içinde başka bir türün değeri, o türün karşılık gelen yöntemine atanır. Bu nedenle, örneğin, bir dizeyi bir int değerine dönüştürmek, Tamsayı sarmalayıcı sınıfından statik bir yöntemle gerçekleştirilir. Aşağıdaki tablo, değerleri dizelere ve tam tersine dönüştürebilen tüm türleri listeler ve karşılık gelen yöntemleri listeler.

TYPE Dönüştürme Yöntemi Dizeden dönüştürme yöntemi

astar

boolean String.valueOf(boolean) new.Boolean(String). boole değeri()

bayt String.valueOf(byte) Byte.parseByte(string, int)

kısa String.valueOf(short) Short.parseShort(string, int)

int String.valueOf(int) Tamsayı.parseTamsayı(dize, int)

long String.valueOf(long) Long.parseLong(String, int)

float String.valueOf(float) Float.parseFloat(String)

double String.valueOf(double) Double.parseDouble(String)

Bir dizeyi Boole değerine dönüştürmek için bir Boole nesnesi oluşturmanız ve ardından değerini sorgulamanız gerekir. Diğer tüm sarmalayıcı sınıfları karşılık gelen yöntemleri içerir ayrıştırmak. yöntemler ayrıştırmak tamsayı türleri iki aşırı yüklenmiş biçimde bulunur: ilki, dizeye ek olarak, sayı sisteminin tabanını temsil eden int türünde ek bir argüman gerektirir - 2'den 32'ye; ikincisi yalnızca bir dize parametresi alır ve varsayılan olarak ondalıktır. Boolean dışındaki tüm durumlarda, varsayım, dizenin uygun türden bir sayıya doğru şekilde dönüştürülemeyen bir değeri temsil etmesi durumunda, bir NumberFormatException'ın atılacağıdır. Boolean sınıfı, "true" (büyük/küçük harfe duyarsız) değerine eşit olmayan herhangi bir parametre dizesinin false değerine sahip bir boole nesnesinin oluşturulmasıyla sonuçlanması kuralına uyar.

Dil tarafından desteklenen formlardan birinde temsil edilen karakterleri dönüştürmenize izin veren yöntemler (örneğin, \b, \uxxxx vb.) char türünde bir değere dönüştürülür ve bunun tersi de yoktur. Tek bir karakter içeren bir String nesnesi almak için, karşılık gelen char değerini parametre olarak ileterek String.valueOf yöntemini çağırmanız yeterlidir.

Ayrıca, dil tarafından desteklenen biçimlerden birinde verilen sayıların dize temsillerini oluşturmanın hiçbir yolu yoktur - sekizli bir sayıyı gösteren baştaki sıfır (O) ve bir işareti olan bir Öküz (veya OX) öneki. onaltılık sayı sistemi. Buna karşılık, tamsayı sarmalayıcı sınıfları, dizeleri uygun türdeki sayısal değerlere dönüştürebilen ve baştaki 0'ın sekizlik olduğunu ve Ox OR Ox öneklerinden birinin onaltılık olduğunu "anlayan" kod çözme yönteminin sürümlerini destekler.

Herhangi bir uygulama sınıfı, bildirimi toString yöntemini uygun şekilde geçersiz kılıyorsa ve parametre olarak iletilen dizeye dayalı olarak bir sınıf nesnesi oluşturan özel bir kurucu sağlıyorsa, yerel nesneleri dizelere dönüştürmek için destek sağlayabilir ve bunun tersi de olabilir. Ayrıca, "null" dize nesnesini (obj değeri null ise) veya obj.toString yönteminin sonucunu döndüren String.valueOf(Object obj) yöntemi de emrinizdedir. String sınıfı, istediğiniz bağımsız değişkenle yalnızca valueOf'u çağırarak herhangi bir türden herhangi bir değeri bir String nesnesine dönüştürmenize izin vermek için valueOf yönteminin aşırı yüklenmiş sürümlerini içerir.

Bu oldukça geniş bir konudur, ancak mümkün olduğunca eksiksiz ve özlü bir şekilde ele almaya çalışacağız. Kısmen, Java ilkel türlerine baktığımızda bu konuya zaten değinmiştik.

Java, tamsayı ve kayan nokta değerleri arasında dönüşümlere izin verir. Her karakter bir Unicode basamağına karşılık geldiğinden, tamsayı ve kayan nokta değerlerini char değerlerine veya tam tersine dönüştürebilirsiniz. Aslında, boole türü, Java'da başka bir ilkel türe dönüştürülemeyen tek ilkel türdür. Ayrıca, başka hiçbir ilkel tür boolean'a dönüştürülemez.

Java'da tür dönüştürme iki çeşittir: örtük Ve açık.

Örtük tür dönüştürme aşağıdaki koşullar yerine getirildiğinde yürütülür:

  1. Her iki tip de uyumludur
  2. Hedef tipin uzunluğu, kaynak tipin uzunluğundan büyük veya ona eşit

Diğer tüm durumlarda, kullanın açık tür dönüştürme.

Ayrıca iki tür dönüşüm vardır:

  1. Genişletme dönüştürme
  2. Daraltma dönüştürme

Genişletme dönüşümü ( genişleyen dönüşüm) bir türün değeri, daha geniş bir geçerli değer aralığıyla daha geniş bir türe dönüştürüldüğünde oluşur. Örneğin, double türünde bir değişkene int türünde bir değişmez değer veya int türünde bir değişkene char türünde bir değer atarsanız, Java genişletme dönüştürmelerini otomatik olarak gerçekleştirir. Örtük bir dönüştürme her zaman genişleyen tiptedir.

Ancak burada bazı küçük tırmıklar olabilir. Örneğin, bir int değeri bir kayan nokta değerine dönüştürülürse. Ve ikili gösterimdeki int değerinin 23'ten fazla anlamlı biti vardır, o zaman kayan nokta tipi tamsayı kısmı için 23 bit içerdiğinden hassasiyet kaybı mümkündür. Tüm düşük bitler Bir kayan noktanın 23 bitlik mantisine uymayan int değerleri atılacaktır, bu nedenle sayı sırası korunsa da kesinlik kaybolur. Aynısı long'ı double'a dönüştürmek için de geçerlidir.

Java tipi dönüştürmeyi genişletmek şu şekilde de gösterilebilir:

Düz çizgiler, veri kaybı olmadan gerçekleştirilen dönüştürmeleri gösterir. Kesikli çizgiler, dönüştürme sırasında bir hassasiyet kaybı olabileceğini gösterir.

Örneğin, bayt türünün 8 bitlik bir genişliğe sahip olmasına ve char türünün 16 olmasına rağmen, bayt türünün neden otomatik olarak (dolaylı olarak) char türüne dönüştürülmediğini biraz açıklamaya değer, aynısı dönüştürme için de geçerlidir. char için kısa türden. Bunun nedeni, bayt ve kısa'nın imzalı veri türleri olması, char'ın ise imzasız olmasıdır. Bu nedenle, bu durumda, açık tip döküm kullanmanız gerekir, çünkü derleyici ne istediğinizi bildiğinizi ve char tipine dönüştürürken bayt ve kısa tiplerin işaret bitinin nasıl işleneceğini açıkça belirtmelidir.

Bir char değerinin davranışı çoğu durumda bir tamsayı türü değerin davranışıyla aynıdır, bu nedenle bir char değeri, bir int veya uzun değerin gerekli olduğu her yerde kullanılabilir. Bununla birlikte, char türünün işaretsiz olduğunu, bu nedenle her iki türün aralığı 16 bit olmasına rağmen kısa türden farklı davrandığını hatırlayın.

kısa s = ( kısa ) 0xffff; // Bu bitler -1 sayısını temsil eder
karakter C = "\ffff"; // Aynı bitler bir unicode karakteri temsil eder
int i1 = s; // Short'dan int'ye çevirmek -1 verir
int i2 = C; // char'ı int'ye dönüştürmek 65535 verir

Daraltma dönüşümü ( daraltma dönüştürme), değer, aralığı orijinal değerden daha geniş olmayan bir tür değerine dönüştürülürse oluşur. Dönüştürmeleri daraltmak her zaman güvenli değildir: örneğin, 13 tamsayı değerini bayta dönüştürmek mantıklıdır, ancak 13000'i bayta dönüştürmek akıllıca değildir çünkü bayt yalnızca -128 ile 127 arasındaki sayıları depolayabilir. Daraltma dönüştürme sırasında veriler kaybolabileceğinden, Java derleyicisi, dönüştürülmekte olan değer belirtilen türün daha dar aralığı içinde kalsa bile, bu tür bir dönüştürmeye itiraz eder:

int i = 13 ;
bayt B = i ; // Derleyici bu ifadeyi çözmeyecek

Kuralın tek istisnası, değişmez değer değişkenin aralığıyla eşleşiyorsa, bir bayt veya kısa değişkene bir tamsayı değişmez değeri (int değeri) atamaktır.

Daraltma dönüştürmesi her zaman açık bir tür dönüştürmedir..

İlkel türlerin açık dönüşümü

Açık bir tür dönüştürme operatörü veya daha kesin olarak, tür dökümü, içinde dönüştürmenin gerçekleştirildiği türün belirtildiği parantezlerdir - (tip). Örneğin:

int i = 13 ;
bayt B = ( bayt ) i ; // int'ten bayta dönüştürmeye zorlama
i = ( int ) 13.456 ; // Double type değişmezin int 13'e zorunlu dönüştürülmesi

İlkel tip döküm en yaygın olarak kullanılır kayan nokta değerlerini tam sayılara dönüştürmek için. nerede kayan nokta değerinin kesirli kısmı basitçe atılır(yani, kayan nokta değeri en yakın tam sayıya değil, sıfıra yuvarlanır). esasen gerçek türün yalnızca tamsayı kısmı alınır ve zaten hedef tamsayı türüne yayınlanmıştır.

Daha kapasitif getirirken tamsayı türü daha az kapasiteli olana, yüksek bitler basitçe atılır. Bu, esasen, döküm değerini hedef türün aralığına bölen modulo ile aynıdır (örneğin, bayt için 256).

Çok büyük bir kesirli sayı, bir tam sayıya dönüştürüldüğünde MAX_VALUE veya MIN_VALUE olur.

Çok büyük çift getirildiğinde batmadan yüzmek Float.POSITIVE_INFINITY veya Float.NEGATIVE_INFINITY olur.

Aşağıdaki tablo, her ilkel tür için dönüştürülebilecekleri türlerin ve dönüştürme yönteminin belirtildiği bir ızgaradır. Mektup n tabloda, dönüştürmenin mümkün olmadığı anlamına gelir. Mektup Y otomatik olarak yapılan bir genişletme dönüşümü anlamına gelir. Mektup İTİBAREN açık bir döküm gerektiren daraltıcı bir dönüşüm anlamına gelir. En sonunda, E* değerin en az anlamlı bitlerden bazılarını kaybedebileceği otomatik genişletme dönüşümü anlamına gelir. Bu, bir int veya long'u bir float veya double'a dönüştürürken olabilir. Kayan nokta türleri, tamsayı türlerinden daha geniş bir aralığa sahiptir, bu nedenle bir int veya uzun, kayan nokta veya çift olarak temsil edilebilir. Ancak, kayan nokta türleri yaklaşık sayılardır ve mantiste her zaman tamsayı türleri kadar anlamlı basamak içermeyebilir.

İfadelerde otomatik tür genişletme

Ayrıca, ifadelerdeki türlerin otomatik olarak yükseltilmesinden (genişletilmesinden) bir kez daha bahsetmekte fayda var. Tamsayı veri tiplerini ve üzerlerindeki işlemleri düşündüğümüzde bununla daha önce karşılaşmıştık ama yine de daha iyi anlamanız için burada hatırlamakta fayda var ve ayrıca doğrudan bu konu ile alakalı. Aşağıdaki örnekte, işaret @ + , , * , / vb.

Yani, türlerin yanı sıra ifadelerdeki tüm tamsayı değişmezleri bayt, kısa Ve karakter genişletmek int . Yukarıda açıklandığı gibi, ifadede başka, daha büyük veri türleri yoksa ( uzun, batmadan yüzmek veya çift). Bu nedenle, yukarıdaki örnek bir derleme hatasına neden olacaktır çünkü değişken C tipi var bayt ve otomatik yükseltmenin bir sonucu olarak b+1 ifadesi türündedir int.

Birleştirilmiş atama ifadelerinde örtük tip döküm

Bu bölüm örtük tip dönüştürmeye (döküm) atıfta bulunsa da, burada bunun bir açıklamasını verdik, çünkü bu durumda ifadelerde otomatik tip genişletme de çalışır ve ardından örtük tip döküm. İşte bir corps de bale. Aşağıdaki örnek, sanırım bunu netleştirecektir. Önceki açıklamada olduğu gibi, işaret @ herhangi bir geçerli operatör anlamına gelir, örneğin + , , * , / vb.

Bunu basit bir örnekle açıklamak gerekir:

bayt b2 = 50 ;
b2 = b2 * 2 ; // derlenmeyecek
b2 *= 2 ; //b2 = b2 * 2 ile eşdeğer olmasına rağmen derler

Örnekteki ikinci satır, otomatik tür genişletme gerçekleştiğinden (ifadelerdeki tamsayı değişmezleri her zaman int'dir) b2*2 ifadesi int türüne sahip olduğundan, ifadelerdeki otomatik tür genişletme nedeniyle derlenmeyecektir. Üçüncü satır, birleştirilmiş atama ifadesindeki örtük tip dökümü içinde çalışacağından, kolayca derlenecektir.

Kutulama/kutudan çıkarma - ilkel türleri sarmalayıcı nesnelere dönüştürme

Boks ve kutu açma da oldukça geniş bir konudur, ancak oldukça basittir.

esasen kutulama ve kutudan çıkarma, ilkel türlerin sarmalayıcı nesnelere dönüştürülmesidir ve bunun tersi de geçerlidir..

İlkel türdeki sarmalayıcı nesneler için yukarıda söylenenlerin hepsi geçerlidir.

İlkel türlerin her biri ayrıştırılırken tablolarda sarmalayıcı sınıflarından bahsedilmiştir. Ama sonra tabloda sadece bir söz vardı.

Yani her ilkel türün bir ağabeyi vardır ve hiç ilkel değildir, alanları ve yöntemleri olan gerçek bir sınıftır. Ve bu tür her bir çift için otomatik dönüştürme mümkündür.

Genellikle, programın çok sayıda matematiksel hesaplaması varsa, kaynaklar açısından daha hızlı ve daha ekonomik olduğu için ilkel türleri kullanmak daha iyidir, ancak bazen ilkel bir türü bir nesneye dönüştürmek gerekir.

Basit bir örnek vereceğim:

int i3 ;
bayt b2 = 3 ;
bayt benimB ;
benimB= b2;
benimB++;
b2= benimB;
i3= benimB;

Bunun neden gerekli olduğu henüz net değilse, o zaman korkutucu değil, sadece bir hatıra olarak bir düğüm atın.

Verilen makale:

  • ekip tarafından yazılmıştır. Sizin için yararlı olacağını umuyoruz. Mutlu okumalar!
  • bu bizim makalelerimizden biri

Tür dönüştürme, yeni başlayan Java programcıları için göz korkutucu görünebilecek bir konudur. Ancak, sizi temin ederiz, aslında her şey basittir. Anlaşılması gereken asıl şey değişkenler arasındaki etkileşimin hangi yasalara göre gerçekleştiğini ve program yazarken bunu unutmayın. Öyleyse, çözelim.

Java'da 2 tür dönüşüm vardır - size yardımcı olacak bir resim:

Tüm "Java Evreni"nin aşağıdakilerden oluştuğunu hatırlayın:

  • ilkel türler (byte, short, int, long, char, float, double, boolean)
  • nesneler

Bu yazıda biz:

  • ilkel değişken türleri için tür dönüştürmeyi düşünün
  • Nesnelerin dönüştürülmesi (String, Scanner, vb.) Bu makalede ele alınmamıştır, çünkü nesnelerle ayrı bir "sihir" gerçekleşir - bu ayrı bir makalenin konusudur.
Otomatik dönüştürme

Peki, "otomatik dönüştürme"nin ne olduğunu bulmaya çalışalım.

Değişken türlerine baktığımızda (makalede) şunu söylediğimizi hatırlayın. değişken bir tür "konteyner"dir Programda daha sonra kullanmak üzere bir değer depolayabilen A. Ayrıca her bir değişken türünün kendi geçerli değer aralığına sahip olduğundan ve kapladığı bellek miktarından bahsetmiştik. İşte yazıldığı yerdeki işaret:

Yani aslında vardığımız şey bu. Ek olarak, geçerli değer aralıklarının ve işgal edilen bellek miktarının verilmesi hiç de kolay olmadı 🙂

Örneğin karşılaştıralım:

1. bayt ve kısa. bayt, kısadan daha küçük bir geçerli değer aralığına sahiptir. Yani, bayt daha küçük bir kutu gibidir ve kısa, daha büyük bir kutudur. Ve bu demek ki kısaca baytı yuvalayabiliriz.

2. bayt ve int. bayt, int'den daha küçük bir geçerli değer aralığına sahiptir. Yani bayt daha küçük bir kutu gibidir ve int daha büyük bir kutudur. Ve bu demek ki baytı int içine yerleştirebiliriz.

3.int ve uzun. int, longdan daha küçük bir geçerli değer aralığına sahiptir. Yani, int daha küçük bir kutu gibidir ve long daha büyük bir kutudur. Ve bu demek ki int'yi uzun olarak iç içe geçirebiliriz.

Bu, otomatik dönüştürmeye bir örnektir. Bu, aşağıdaki resim şeklinde şematik olarak gösterilebilir:

Bunun pratikte nasıl çalıştığına bakalım.

Örnek 1

Kod #1 - Bu kodu bilgisayarınızda çalıştırırsanız,

sınıf Testi ( public static void main(String args) ( byte a = 15; byte b = a; System.out.println(b); ) )

sınıf Testi(

bayt a = 15 ;

bayt b = a ;

Kod #2 - Bu kodu bilgisayarınızda çalıştırırsanız, konsol 15 sayısını gösterecek

sınıf Testi ( public static void main(String args) ( byte a = 15; int b = a; System.out.println(b); ) )

sınıf Testi(

public static void main(String args )(

bayt a = 15 ;

int b = bir ;

Sistem. dışarı . println(b);

Ve-ve-ve? Bunu düşünüyor musun konsola aynı sayının kaç kez yazdırıldığı, ve kod #1, kod #2'den yalnızca b değişkeninin türünde farklıdır peki aralarında bir fark yok mu? Eöyle değil.

Kod #2 şunları içerir: otomatiktür dönüştürme , ancak 1 numaralı kodda - hayır:

Sayı temelde aynı olmasına rağmen, şimdi b'de hakkında daha fazla disk alanı kaplayan daha büyük bir kapsayıcı. Bu durumda JVM sizin için otomatik dönüşümler gerçekleştirir. Bunu biliyor int bundan fazla bayt .

Döküm

Başka bir şey, daha büyük bir kaptan daha küçük bir şeye bir şey aktarmaya çalışıyorsanız.

Daha büyük bir konteynırın küçüğüne sığacak bir şey içerdiğini biliyor olabilirsiniz - ancak JVM bunu bilmiyor ve sizi hatalardan korumaya çalışıyor.

Bu nedenle, durumun kontrol altında olduğunu “doğrudan söylemelisiniz”:

sınıf Testi ( public static void main(String args) ( int a=0; uzun b=15; a = (int) b; ) )

sınıf Testi(

public static void main(String args )(

int a = 0 ;

uzun b = 15 ;

a = (int ) b ;

buraya ekledik (int)ön B. değişken ise aörneğin, bayt, parantez içinde (bayt). Genel formül şöyle görünür:

"(daha büyük) değere sahip" diyor B ihtiyacım olan (hedef) türden bir değişken int ".

Bir şeyler ters gittiyse.

Şimdiye kadar, tam olarak ne yaptığımızı bildiğimizi varsayarak durumlara baktık. Ama ya oraya sığmayan bir şeyi bir kaba koymaya çalışırsanız?

Kapta yalnızca “uygun” olanın kalacağı ortaya çıktı. Örneğin, kayan noktalı sayıların kesirli kısmı "kesilmiş" olacaktır:

//örnek 1 sınıf Test ( public static void main(String args) ( double a=11.2345; int b=(int)a; System.out.println(b); // konsol 11 sayısını gösterecek) )

//örnek 1

sınıf Testi(

public static void main(String args )(

çift ​​a = 11.2345 ;

int b = (int ) a ;

Sistem. dışarı . println(b); // konsol 11 sayısını gösterecek

Unutulmamalıdır ki, kesirli kısım yuvarlak değil, fakat atılan.

Ama sınırların dışında bir sayı koymaya çalışırsak ne olur? Örneğin, bayt olarak (-128 ile 127 arasındaki bayt aralığı) 128? Sizce 1 alır mıyız? Numara. -128 alırız:

class Test ( public static void main(String args) ( double a=128; byte b=(byte)a; System.out.println(b); //konsolda -128 göreceğiz) )

Böyle bir dönüşümde bir değişkenin değeri hesaplanabilir, ancak programcının amacı, değerin sınırların dışında olduğu bir durumu önlemektir, çünkü bu yanlış program çalışmasına yol açabilir.

Görevler:
  1. char türleri de dahil olmak üzere tüm ilkel türlerin derleyici dönüşümlerine sırayla yazın ve şöyle bir tablo yapın:
bayt kısa karakter int uzun batmadan yüzmek çift boole
bayt
kısa
karakter
int
Uzun
batmadan yüzmek
çift
boole

Kavşakta şunları yazın: a - dönüştürme otomatik olarak gerçekleşirse, - açık bir dönüştürme kullanmanız gerekiyorsa, x - dönüştürme mümkün değilse.

* bir türü kendine çevirmeye denir birebir aynı- yazmak gerekli değildir

  1. Her ilkel türün hangi boyutta olduğuna tekrar bakın. Hangi türlerin nereye gittiğini gösteren bir blok diyagram oluşturmaya çalışın. "Dönüşümü genişletme" ve "dönüşüm daraltma" etiketli okları kaydırın.
sorular

Junior Java Developer pozisyonu için görüşme yaparken, size şu sorular sorulabilir:

İlkel veri türlerinin dönüştürülmesi hakkında ne biliyorsunuz, herhangi bir veri kaybı var mı, bir boole türünü dönüştürmek mümkün mü?

Soruyu cevaplamaya çalışın.

Özetlemek:
  • Daha küçük bir kabın içeriğini daha büyük bir kaba "koyarsanız", dönüştürme otomatiktir ve hiçbir hata oluşmamalıdır.
  • "Daha büyük bir kaptan daha küçük olana bir değer" koyma ihtiyacı varsa, dikkatli olmanız ve açık tip döküm kullanmanız gerekir.
  • Şamandıra veya çiftten integral tiplere döküm yaparken, kesirli kısım yuvarlanmaz, ancak basitçe atılır.
  • Boole türü, türlerin hiçbirine atanmaz.
  • Karakter türü, UNICODE sistemindeki bir karakter kodu gibi sayısal türlere dönüştürülür.
  • Sayı kapsayıcısından büyükse, sonuç tahmin edilemez olacaktır.

Bu makale, tip döküm konusundaki malzemenin yalnızca bir kısmını açıklamaktadır. Ayrıca nesne türü yayınları, dize yayınları (sonuçta bir dizede her şey yazılabilir, değil mi?) ve ifadelerde otomatik tür yükseltme vardır.

Umarız yazımız sizin için faydalı olmuştur. Kiev'deki Java kurslarımıza da kayıt yaptırmak mümkündür. Sıfırdan eğitim veriyoruz. Detaylı bilgiyi web sitemizde bulabilirsiniz.


Dipnot: Bu ders, tür dönüştürme konularına ayrılmıştır. Java güçlü bir şekilde yazılmış bir dil olduğundan, derleyici ve sanal makine, programın güvenilir bir şekilde çalışmasını sağlamak için her zaman türlerin farkındadır. Bununla birlikte, çoğu durumda, programın mantığını uygulamak için şu veya bu dönüşüm gerçekleştirilmelidir. Öte yandan, Java türleri arasında bazı güvenli geçişler geliştirici için örtük bir şekilde yapılabilir ve bu da programın nasıl çalıştığının yanlış anlaşılmasına yol açabilir. Ders, her türlü dönüşümü ve ardından programdaki uygulanabilecek tüm durumları kapsar. Değişken türlerinin ve saklayabilecekleri değer türlerinin sınıflandırılmasının başlamasıyla sona erer. Bu konu ileriki derslerde daha detaylı olarak tartışılacaktır.

Bütün bunlar ne anlama geliyor? Sırayla başlayalım. Basit türler için genişletme, daha az kapasiteli bir türden daha geniş bir türe geçiş yapılması anlamına gelir. Örneğin, bayt türünden (uzunluk 1 bayt) int türüne (uzunluk 4 bayt) kadar. Bu tür dönüştürmeler, yeni türün her zaman eski türde depolanan tüm verileri içermesi garanti edildiğinden güvenlidir ve bu nedenle veri kaybı olmaz. Bu nedenle derleyici, geliştirici için fark edilmeden kendisi uygular:

bayt=3; int a=b;

Son satırda byte türündeki b değişkeninin değeri otomatik olarak a değişkeninin türüne (yani int ) dönüştürülür, bunun için özel bir işlem yapılması gerekmez.

Aşağıdaki 19 dönüşüm genişliyor:

  • bayttan kısaya, int, uzun, kayan nokta, çift
  • kısadan int'ye, uzun, kayan nokta, çift
  • karakterden int'ye, uzun, kayan nokta, çift
  • int'den long'a , float , double
  • uzundan yüzmeye, çifte
  • ikiye katlamak

Veri kaybı olmadan, daha kısa veya eşit uzunluktaki (byte , short ) türlerden char'a veya tam tersi char'dan short'a dönüştüremeyeceğinizi unutmayın. Bunun nedeni, diğer tamsayı türlerinin aksine char öğesinin işaretsiz olmasıdır.

Ancak, özel durumlarda genişleme ile bile verilerin yine de bozulabileceği unutulmamalıdır. Bir önceki derste zaten tartışılmıştı, bu int değerlerinin float tipine dökümü ve uzun değerlerin float veya double tipine dökümüdür. Bu kesir türleri, karşılık gelen tamsayılardan çok daha büyük sayıları barındırabilse de, daha az anlamlı basamakları vardır.

Bu örneği tekrarlayalım:

uzun a=1111111111111L; kayan nokta f = a; a = (uzun)f; yazdır(a);

Sonuç:

Ters dönüşüm - daralma - geçişin daha kapasitif bir türden daha az kapasitif olana gerçekleştirildiği anlamına gelir. Böyle bir dönüşümle, veri kaybetme riski vardır. Örneğin, bir int 127'den büyükse, bayta dönüştürüldüğünde sekizden eski bit değerleri kaybolur. Java'da böyle bir dönüştürme açıkça yapılmalıdır, yani. koddaki programcı, böyle bir dönüştürme yapmayı planladığını ve veri kaybetmeye hazır olduğunu açıkça belirtmelidir.

Aşağıdaki dönüşümler daralmaktadır:

  • bayttan karaktere
  • kısadan bayta, char
  • karakterden bayta, kısa
  • int'den bayta, kısa, karaktere
  • uzundan bayta, kısa, karakter, int
  • bayta yüzer, kısa, karakter, int, uzun
  • çiftten bayta, kısa, karakter, int, uzun, kayan nokta

Bir tamsayı türünü daha dar bir tamsayı türüne daraltırken, yeni türe uymayan tüm yüksek dereceli bitler basitçe atılır. Daha doğru bir sonuç elde etmek için herhangi bir yuvarlama veya başka işlem yapılmaz:

yazdır((bayt)383); print((bayt)384); print((bayt)-384);

Sonuç:

İşaret bitinin daraltma sırasında herhangi bir etkisinin olmadığı, çünkü basitçe atıldığı görülebilir - zıt sayıların (384 ve -384) dökümünün sonucu aynı çıktı. Sonuç olarak, yalnızca kesin mutlak değer değil, aynı zamanda miktarın işareti de kaybolabilir.

Bu, char türü için de geçerlidir:

karakter c=40000; print((kısa)c);

Sonuç:

Kesirli bir türü bir tamsayı türüne daraltmak daha karmaşık bir prosedürdür. İki aşamada gerçekleştirilir.

İlk adımda, hedef türü uzunsa kesirli değer long'a, aksi takdirde int'ye dönüştürülür (hedef türü byte , short , char veya int 'dir). Bunu yapmak için, orijinal kesirli sayı önce matematiksel olarak sıfıra yuvarlanır, yani kesirli kısım basitçe atılır.

Örneğin, 3.84 sayısı 3'e yuvarlanır ve -3.84 -3 olur. Bu durumda, özel durumlar ortaya çıkabilir:

  • orijinal kesirli değer NaN ise, o zaman ilk adımın sonucu seçilen türden 0'dır (yani int veya long );
  • orijinal kesirli değer pozitif veya negatif sonsuz ise, o zaman ilk adımın sonucu seçilen tür için sırasıyla maksimum veya minimum olası değer olacaktır (yani int veya long için);
  • son olarak, kesirli değer sonlu bir değerse, ancak yuvarlamanın bir sonucu olarak sayının modül olarak seçilen tür için çok büyük olduğu ortaya çıktıysa (yani int veya long için), o zaman önceki paragrafta olduğu gibi, sonucu ilk adım, sırasıyla, bu türün maksimum veya minimum olası değeri olacaktır. Yuvarlamanın sonucu, seçilen türün değer aralığına uyuyorsa, ilk adımın sonucu olacaktır.
  • ve int oldukça açıktır - kesirli sonsuzluklar sırasıyla bu türlerin minimum ve maksimum olası değerlerine dönüştürülmüştür. Sonraki üç tür (short , char , byte ) için sonuç, aslında, dönüştürme prosedürünün ikinci adımına göre int için elde edilen değerlerin daha da daraltılmasıdır. Ve bu, açıklandığı gibi, sadece yüksek bitleri atarak yapılır. Bit biçimindeki olası en küçük değerin 100.000 olarak temsil edildiğini hatırlayın (int için yalnızca 32 bit, yani bir ve 31 sıfır). Mümkün olan maksimum 1111..111'dir (31 adet). Yüksek bitleri atarak, her üç tür için de aynı olan negatif sonsuz için 0 sonucunu elde ederiz. Pozitif sonsuzluk için, tüm bitleri eşit olan bir sonuç elde ederiz. 1

    Sonuç olarak, boole türündeki ilkel değerlerin yalnızca özdeş dönüşümlere katılabileceği gerçeğine bir kez daha dikkat edelim.

Bazen, belirli bir türde bir değere sahip olduğunuzda durumlar ortaya çıkar ve bunu farklı bir türdeki bir değişkene atamanız gerekir. Bazı tipler için bu, tip dökümü olmadan yapılabilir, bu gibi durumlarda otomatik tip dönüştürmeden bahsedilebilir. Java'da otomatik dönüştürme, yalnızca hedef değişkenin sayısal gösterimi orijinal değeri tutacak kadar kesin olduğunda mümkündür. Böyle bir dönüştürme, örneğin, bir değişmez sabit ya da byte ya da kısa türündeki bir değişkenin değeri, int türündeki bir değişkene girildiğinde gerçekleşir. denir eklenti (genişleme) veya arttırmak (terfi), çünkü daha küçük bit derinliği türü daha büyük bir uyumlu türe genişletilir (yükseltilir). Bir int'nin boyutu her zaman bir bayt için izin verilen aralık içindeki sayıları tutacak kadar büyüktür, bu nedenle bu durumlarda açık bir yayın operatörü gerekli değildir. Çoğu durumda bunun tersi doğru değildir, bu nedenle bir byte değişkenine bir int değeri dönüştürmek için bir cast operatörü kullanılmalıdır. Bu prosedür bazen denir daralma (daralma), çünkü çevirmene, değerin istediğiniz türde bir değişkene sığdırmak için dönüştürülmesi gerektiğini açıkça söylüyorsunuz. Belirli bir türe değer atamak için, parantez içinde o türün önüne koyun. Aşağıdaki kod parçacığı, bir kaynak türün (bir int değişkeni) bir hedef türe (bir bayt değişkeni) dönüştürülmesini gösterir. Böyle bir işlem sırasında tamsayı değeri, bayt türü için izin verilen aralığın dışındaysa, modulo bölme ile izin verilen bayt aralığına düşürülür (bir sayıya göre modulo bölmenin sonucu, bu sayıya göre bölmenin geri kalanıdır) ,

int a = 100;
baytb = (bayt) a;

2.2.1. İfadelerde otomatik tür dönüştürme

Bir ifadenin değeri değerlendirilirken, ara sonuçları depolamak için gereken kesinlik, genellikle nihai sonucu temsil etmek için gerekenden daha büyük olmalıdır,

bayt a = 40;
bayt b = 50;
bayt ile = 100;
int d = a* b / c;

Ara ifadenin (a * b) sonucu, bayt türü için izin verilen değer aralığının ötesine geçebilir. Bu nedenle Java, ifadenin her bir bölümünü int yazacak şekilde otomatik olarak yükseltir, bu nedenle ara sonuç (a*b) için yeterli alan vardır.

Otomatik tür dönüştürme bazen beklenmeyen derleyici hata mesajlarına neden olabilir. Örneğin aşağıda gösterilen kod doğru gibi görünse de çeviri aşamasında hata mesajı veriyor. İçinde bayt tipine tam olarak uyması gereken 50*2 değerini bir bayt değişkenine yazmaya çalışıyoruz. Ancak sonuç türünün otomatik olarak int'ye dönüştürülmesi nedeniyle, çevirmenden bir hata mesajı alıyoruz - sonuçta, bir int'yi bir bayta dönüştürürken hassasiyet kaybı meydana gelebilir.

bayt b = 50;
b = b*2:
^ = için uyumsuz tür. İnt'yi bayta dönüştürmek için açık döküm gerekli.
(Uyumsuz tür = için. Açık dönüştürme gerekliintbayt)

Düzeltilmiş metin:
baytb = 50;
b = (bayt) (b*2);

bu da b'nin doğru 100 değeriyle doldurulmasına neden olur.

İfade byte, short ve int türündeki değişkenleri kullanıyorsa, taşmayı önlemek için tüm ifadenin türü otomatik olarak int'ye yükseltilir. İfadedeki en az bir değişkenin türü uzunsa, tüm ifadenin türü de uzun olarak yükseltilir. L (veya 1) ile bitmeyen tüm tamsayıların int türünde olduğunu unutmayın.

Bir ifade, float türünde işlenenler içeriyorsa, tüm ifadenin türü otomatik olarak float olarak yükseltilir. İşlenenlerden en az biri double türündeyse, tüm ifadenin türü double olarak yükseltilir. Varsayılan olarak Java, tüm kayan nokta değişmezlerini double türünde olarak değerlendirir. Aşağıdaki program, bir ifadedeki her bir değerin türünün, her ikili operatörün ikinci işleneniyle eşleşecek şekilde nasıl yükseltildiğini gösterir.

sınıf Tanıtımı(
public static void main(String args )(
baytb=42;
ile karakter= "a';
şort = 1024;
int ben = 50000;
kayan nokta f = 5.67f;
iki katına =.1234;
çift ​​sonuç = (f*b) + (i/ c) - (d* s);
Sistem, dışarı. println ((f* b)+ "+ "+ (i / c)+ "-" + (d* s));
Sistem, dışarı. println("sonuç = "+sonuç); )
}

f*b alt ifadesi, bir bayt ile çarpılan bir şamandıradır, bu nedenle otomatik olarak şamandıraya yükseltilir. Sonraki i/c alt ifadesinin türü (int bölü char) int'ye yükseltilir. Benzer şekilde, d*s alt ifadesi (kısa ile çift çarpım) iki katına yükseltilir. Hesaplamaların bir sonraki adımında, float, int ve double türlerinin üç ara sonucuyla ilgileniyoruz. İlk olarak, ilk ikisini eklerken, int türü yüzdürmeye yükseltilir ve sonuç bir yüzer sonuçtur. Bundan bir çift değer çıkarıldığında, sonuç türü ikiye yükseltilir. Tüm ifadenin nihai sonucu bir çift değerdir.

Artık tamsayılar, gerçekler, semboller ve booleler dahil tüm basit türleri gördüğümüze göre, tüm bilgileri bir araya getirmeye çalışalım. Aşağıdaki örnek, basit türlerin her birinin değişkenlerini oluşturur ve bu değişkenlerin değerlerini görüntüler.

sınıf SimpleTypes(
public static void main(String args ) (
bayt b = 0x55;
kısa s = 0x55ff;
int ben = 1000000;
uzun l = 0xffffffffL;
ile karakter= 'a';
kayan nokta f= .25f;
çift ​​d = .00001234;
boolean bool = doğru;
System.out.println("bayt b = " + b);
System.out.println("kısa s = " +s);
System.out.println("int ben =" + ben);
System.out.println("uzun 1 = " + l);
System.out.println("char ile=” + ile);
System.out.println("float f = " + f);
System.out.println("çift d = " + d);
System.out.println("boolean bool =” + bool); )
}

Bu programı çalıştırdığınızda, aşağıda gösterilen çıktıyı almalısınız:

bayt b = 85
şort = 22015
int ben = 1000000
uzun 1 = 4294967295
ile karakter= bir
kayan nokta f = 0.25
çift ​​d=1.234e-005
boolean bool = doğru

Bazılarını onaltılık olarak belirtmemize rağmen, tam sayıların ondalık gösterimde yazdırıldığını unutmayın.