JavaRush /Java Blog /Random-IT /Casting (conversione) di tipi primitivi in Java

Casting (conversione) di tipi primitivi in Java

Pubblicato nel gruppo Random-IT
Ciao! Durante l'utilizzo di JavaRush, ti sei imbattuto in tipi primitivi più di una volta. Ecco un breve elenco di ciò che sappiamo su di loro:
  1. Non sono oggetti e rappresentano un valore archiviato in memoria
  2. Esistono diversi tipi di tipi primitivi:
    • Numeri interi - byte, short, int,long
    • Numeri in virgola mobile (frazionari) - floatedouble
    • Booleano -boolean
    • Simbolico (per indicare lettere e numeri) -char
  3. Ognuno di essi ha il proprio intervallo di valori:
Tipo primitivo Dimensioni in memoria Intervallo di valori
byte 8 bit da -128 a 127
corto 16 bit da -32768 a 32767
car 16 bit da 0 a 65536
int 32 bit da -2147483648 a 2147483647
lungo 64 bit da -9223372036854775808 a 9223372036854775807
galleggiante 32 bit da (2 alla potenza -149) a ((2-2 alla potenza -23)*2 alla potenza 127)
Doppio 64 bit da (-2 alla potenza di 63) a ((2 alla potenza di 63) - 1)
booleano 8 (se utilizzato in array), 32 (se utilizzato in non array) vero o falso
Ma, oltre ai valori, i tipi differiscono anche per la dimensione della memoria. intci vuole più di byte. A long- più di short. La quantità di memoria occupata dai primitivi può essere paragonata alle bambole nidificanti: Espansione e contrazione dei tipi primitivi - 2 all'interno della bambola nidificante c'è spazio libero. Più grande è la bambola da nidificazione, maggiore è lo spazio. longPossiamo facilmente metterne uno più piccolo all'interno di una grande bambola da nidificazione int. Si adatta facilmente e non è necessario fare nulla in più. In Java, quando si lavora con le primitive, questa si chiama conversione automatica. In un altro modo si chiama espansione. Ecco un semplice esempio di estensione:
public class Main {

   public static void main(String[] args) {

       int bigNumber = 10000000;

       byte littleNumber = 16;

       bigNumber = littleNumber;
       System.out.println(bigNumber);
   }
}
Qui assegniamo un valore bytea una variabile int. L'assegnazione è andata a buon fine e senza problemi: il valore memorizzato in byteoccupa meno spazio di memoria di quello che “sta” in int. La “piccola bambola da nidificazione” (valore byte) si adatta facilmente alla “grande matrioska” (variabile int). Un'altra questione è quando provi a fare il contrario: inserisci un valore elevato in una variabile che non è progettata per tali dimensioni. In linea di principio, questo trucco non funzionerà con le vere bambole da nidificazione, ma in Java funzionerà, ma con sfumature. Proviamo a inserire un valore intin una variabile short:
public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = bigNumber;//error!
   System.out.println(bigNumber);
}
Errore! Il compilatore capisce che stai cercando di fare qualcosa di non standard e inserisce una bambola matrioska grande ( int) all'interno di una piccola ( short). Un errore di compilazione in questo caso è un avvertimento da parte del compilatore: “ Ehi, sei sicuro di volerlo fare? “Se sei sicuro, dillo al compilatore: “ Va tutto bene, so cosa sto facendo!” Questo processo è chiamato conversione esplicita del tipo o restringimento . Per effettuare un restringimento, devi indicare esplicitamente il tipo a cui vuoi trasmettere il tuo valore. In altre parole, rispondi alla domanda del compilatore: " Bene, in quale di queste bamboline vuoi mettere questa grande bambola?" " Nel nostro caso sarà simile a questo:
public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
Abbiamo esplicitamente indicato che vogliamo adattare il valore inta una variabile shorte assumercene la responsabilità. Il compilatore, vedendo l'indicazione esplicita di un tipo più ristretto, esegue una conversione. Quale sarà il risultato? Output della console: -27008 Un po' inaspettato. Perché esattamente così? In realtà è semplice. Avevamo il valore originale: 10000000. Era memorizzato in una variabile intche occupava 32 bit e in forma binaria appariva così: Espansione e contrazione dei tipi primitivi - 3 Scriviamo questo valore nella variabile short, ma può memorizzare solo 16 bit! Di conseguenza, solo i primi 16 bit del nostro numero verranno spostati lì, il resto verrà scartato. Di conseguenza, la variabile shortconterrà il valore Espansione e contrazione dei tipi primitivi - 4, che in forma decimale è esattamente uguale a -27008. Ecco perché il compilatore “ha chiesto conferma” sotto forma di cast esplicito a un tipo specifico. In primo luogo, mostra che ti assumi la responsabilità del risultato e, in secondo luogo, indica al compilatore quanto spazio allocare durante il cast dei tipi. Dopotutto, se nell'ultimo esempio avessimo castato intsu type byte, e non su short, avremmo a disposizione solo 8 bit, non 16, e il risultato sarebbe stato diverso. Per i tipi frazionari ( floate double), il restringimento avviene in modo diverso. Se provi a convertire un numero di questo tipo in un tipo intero, la sua parte frazionaria verrà scartata.
public static void main(String[] args) {

   double d = 2.7;

   long x = (int) d;
   System.out.println(x);
}
Uscita console: 2

Tipo di dati car

Sai già che il tipo char viene utilizzato per visualizzare singoli caratteri.
public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';

}
Ma ha una serie di caratteristiche che è importante comprendere. Consideriamo nuovamente la tabella con gli intervalli di valori:
Tipo primitivo Dimensioni in memoria Intervallo di valori
byte 8 bit da -128 a 127
corto 16 bit Da -32768 a 32767
car 16 bit da 0 a 65536
int 32 bit da -2147483648 a 2147483647
lungo 64 bit da -9223372036854775808 a 9223372036854775807
galleggiante 32 bit da (2 alla potenza -149) a ((2-2 alla potenza -23)*2 alla potenza 127)
Doppio 64 bit da (-2 alla potenza di 63) a ((2 alla potenza di 63)-1)
booleano 8 (se utilizzato in array), 32 (se utilizzato in non array) vero o falso
La tipologia charha un range numerico da 0 a 65536. Ma cosa significa? Dopotutto, charquesti non sono solo numeri, ma anche lettere, segni di punteggiatura... Il fatto è che i valori charsono memorizzati in Java in formato Unicode. Abbiamo già incontrato Unicode in una delle lezioni precedenti. Probabilmente ricorderai che Unicode è uno standard di codifica dei caratteri che include caratteri provenienti da quasi tutte le lingue scritte del mondo. In altre parole, questo è un elenco di codici speciali in cui è presente un codice per quasi tutti i caratteri di qualsiasi lingua. La tabella generale Unicode è molto grande e, ovviamente, non ha bisogno di essere imparata a memoria. Eccone, ad esempio, una parte: Espansione e contrazione dei tipi primitivi - 5 La cosa principale è comprendere il principio di memorizzazione dei valori chare ricordare che conoscendo il codice di un simbolo specifico, è sempre possibile inserirlo nel programma. Proviamolo con un numero casuale:
public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
Output della console: 耰 Questo è il formato in cui i caratteri vengono archiviati in Java char. Ogni carattere corrisponde a un numero: un codice numerico di 16 bit o due byte. Unicode 32816 corrisponde al carattere 耰. Presta attenzione a questo momento. In questo esempio abbiamo utilizzato la variabile int. Occupa 32 bit di memoria , mentre char16 . Qui abbiamo scelto perché il numero di cui abbiamo bisogno, 32816, è fuori portata . Sebbene la dimensione , come short, sia di 16 bit, non ci sono numeri negativi nell'intervallo, quindi l'intervallo "positivo" è due volte più grande (65536 invece di 32767 ). Possiamo usare , purché il nostro codice rientri nell'intervallo 65536. Ma se creiamo un numero , occuperà più di 16 bit. E quando si restringono i tipi: intshortcharcharcharshortintint >65536
char c = (char) x;
i bit extra verranno scartati e il risultato sarà del tutto inaspettato.

Caratteristiche dell'addizione di caratteri e numeri interi

Diamo un'occhiata a questo insolito esempio:
public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i+c);
   }
}
Uscita console: 50 O_O Dov'è la logica? 1+1, da dove viene il 50?! Sai già che i valori charsono archiviati in memoria come numeri compresi tra 0 e 65536, che rappresentano l'Unicode del nostro carattere. Espansione e contrazione dei tipi primitivi - 6 Quindi eccolo qui. Quando eseguiamo l'addizione char, alcuni tipi interi charvengono convertiti nel numero che corrisponde ad esso in Unicode. Quando nel nostro codice abbiamo aggiunto 1 e '1', il simbolo '1' è stato trasformato nel suo codice, che è 49 (puoi verificarlo nella tabella sopra). Pertanto, il risultato è diventato uguale a 50. Prendiamo ancora una volta il nostro vecchio amico -come esempio e proviamo ad sommarlo con un numero.
public static void main(String[] args) {

   char c = '耰';
   int x = 200;

   System.out.println(c + x);
}
Output della console: 33016 Abbiamo già scoperto che corrisponde al codice 32816. E quando aggiungiamo questo numero e 200, otteniamo esattamente il nostro risultato: 33016 :) Il meccanismo di funzionamento, come puoi vedere, è abbastanza semplice.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION