1. Tipografia

Typecasting in Java

Le variabili di tipi primitivi (con l'eccezione del booleantipo) vengono utilizzate per memorizzare vari tipi di numeri. Sebbene i tipi di variabili non siano mai cambiati, c'è un posto dove puoi convertire da un tipo all'altro. E quel posto è l'assegnazione .

È possibile assegnare tra loro variabili di tipo diverso. Quando si esegue questa operazione, il valore di una variabile di un tipo viene convertito in un valore di un altro tipo e assegnato alla seconda variabile. A questo proposito, possiamo identificare due tipi di conversione di tipo: l'allargamento e il restringimento.

L'allargamento è come spostare un valore da un cestino piccolo a uno grande: questa operazione è senza soluzione di continuità e indolore. Il restringimento si verifica quando sposti un valore da un cestino grande a uno piccolo: potrebbe non esserci abbastanza spazio e dovrai buttare via qualcosa.

Ecco i tipi, ordinati per dimensione del cestino:

Typecasting in Java 2


2. Ampliamento delle conversioni di tipo

Spesso è necessario assegnare una variabile di un tipo numerico a una variabile di un altro tipo numerico. Come si fa a farlo?

Java ha 4 tipi interi:

Tipo Misurare
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

Le variabili memorizzate in cestini più piccoli possono sempre essere assegnate a variabili memorizzate in cestini più grandi.

int, shorte bytele variabili possono essere facilmente assegnate alle longvariabili. shorte bytele variabili possono essere assegnate alle intvariabili. E bytele variabili possono essere assegnate alle shortvariabili.

Esempi:

Codice Descrizione
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
Questo codice verrà compilato correttamente.

Tale conversione, da un tipo più piccolo a uno più grande, è chiamata conversione del tipo di ampliamento .

E i numeri reali?

Con loro, tutto è uguale: le dimensioni contano:

Tipo Misurare
float 4 bytes
double 8 bytes

floatle variabili possono essere assegnate alle doublevariabili senza problemi. Ma le cose sono più interessanti con i tipi interi.

È possibile assegnare qualsiasi variabile intera a una floatvariabile. Anche il longtipo, che è lungo 8 byte. E puoi assegnare quello che vuoi - qualsiasi variabile o floatvariabile intera - a una doublevariabile:

Codice Nota
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

Si noti che la conversione in un tipo reale può comportare una perdita di precisione a causa della mancanza di cifre significative sufficienti.

Quando si converte da numeri interi a numeri in virgola mobile, le parti di ordine inferiore dei numeri possono essere scartate. Ma poiché si ritiene che i numeri frazionari memorizzino valori approssimati, tali operazioni di assegnazione sono consentite.


3. Restringere le conversioni di tipo

E le altre possibilità? Cosa succede se è necessario assegnare un longvalore a una intvariabile?

Immagina una variabile come un paniere. Abbiamo basket di varie dimensioni: 1, 2, 4 e 8 byte. Non è un problema trasferire le mele da un cestino più piccolo a uno più grande. Ma quando si passa da un cesto più grande a uno più piccolo, alcune mele potrebbero andare perse.

Questa trasformazione, da un tipo più grande a un tipo più piccolo, è chiamata conversione del tipo di restringimento . Quando si esegue un'operazione di assegnazione come questa, parte di un numero potrebbe semplicemente non rientrare nella nuova variabile e potrebbe quindi essere scartata.

Quando restringiamo un tipo, dobbiamo dire esplicitamente al compilatore che non stiamo commettendo un errore, che stiamo deliberatamente scartando parte del numero. L'operatore typecast viene utilizzato per questo. È un nome di tipo tra parentesi .

In tali situazioni, il compilatore Java richiede al programmatore di specificare l'operatore typecast. In generale, sembra così:

(type) expression

Esempi:

Codice Descrizione
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
Ogni volta l'operatore typecast deve essere indicato in modo esplicito

Qui aè uguale a 1e forse l'operatore typecast sembra eccessivo. Ma se afossero più grandi?

Codice Descrizione
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

Un milione si inserisce perfettamente in a longe in an int. Ma quando si assegna un milione a una shortvariabile, i primi due byte vengono scartati e vengono conservati solo gli ultimi due byte. E quando si assegna a a byte, l'unica cosa che rimane è l'ultimo byte.

Come sono disposti i numeri in memoria:

Tipo Notazione binaria Notazione decimale
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

chartipo

A char, come a short, occupa due byte, ma per convertirne uno in un altro è sempre necessario utilizzare un operatore typecast. Il problema qui è che il shorttipo è firmato e può contenere valori da -32,768a +32,767, ma il chartipo non è firmato e può contenere valori da 0a 65,535.

I numeri negativi non possono essere memorizzati in a char, ma possono essere memorizzati in a short. E a shortnon può memorizzare numeri maggiori di 32,767, ma tali numeri possono essere memorizzati in a char.


4. Tipo di un'espressione

Cosa succede se nella stessa espressione vengono utilizzate variabili di tipi diversi? Logicamente, comprendiamo che prima devono essere convertiti in un tipo comune. Ma quale?

A quello più grande, ovviamente.

Java converte sempre nel tipo più grande. In parole povere, uno dei tipi viene prima ampliato e solo successivamente l'operazione viene eseguita utilizzando valori dello stesso tipo.

Se an inte a longsono coinvolti in un'espressione, il valore di intsarà convertito in a longe solo allora l'operazione procederà:

Codice Descrizione
int a = 1;
long b = 2;
long c = a + b;
averrà ampliato in a longe quindi si verificherà l'addizione.

Numeri in virgola mobile

Se un numero intero e un numero in virgola mobile ( floato double) sono coinvolti in un'espressione, il numero intero verrà convertito in un numero in virgola mobile ( floato double) e solo allora verrà eseguita l'operazione.

Se l'operazione coinvolge a floate a double, verrà floatconvertito in a double. Che in realtà è previsto.

Sorpresa

I tipi byte, shorte charvengono sempre convertiti in intquando interagiscono tra loro. C'è una buona ragione per cui il inttipo è considerato il tipo intero standard.

Se moltiplichi a byteper a shortottieni un int. Se moltiplichi a byteper a byteottieni un int. Anche se aggiungi a bytee a byte, ottieni un int.

Ci sono diverse ragioni per questo. Esempi:

Codice Descrizione
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 120is 13,200, che è leggermente maggiore del valore massimo del bytetipo:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120is 230, anch'esso leggermente maggiore del valore massimo del bytetipo:127

In generale, moltiplicando un numero a 8 bit (1 byte) per un numero a 8 bit (1 byte), otteniamo un numero che occupa bit a 16 bit (2 byte)

Di conseguenza, tutte le operazioni con tipi interi inferiori a intvengono sempre immediatamente convertite in ints. Ciò significa che se si desidera archiviare il risultato del calcolo in una variabile di un tipo più piccolo di un int, sarà sempre necessario specificare esplicitamente l'operatore typecast.

Esempi:

Codice Descrizione
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
L' byte * byteespressione sarà unint
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
L' byte + byteespressione sarà unint
byte a = 1;
byte b = (byte) (a + 1);
L' byte + intespressione sarà un int
Quello letterale è un int.

5. Una sfumatura importante

L'operatore typecast ha una priorità abbastanza alta.

Ciò significa che se un'espressione contiene, ad esempio, l'addizione e un operatore di typecast, il typecast verrà eseguito prima dell'addizione.

Esempio:

Codice Descrizione
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
L'operatore typecast verrà applicato solo alla avariabile, che è già un file byte. Questo codice non verrà compilato.
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
Questo è il modo corretto.

Se si desidera convertire l'intera espressione in un tipo specifico e non solo un componente dell'espressione, racchiudere l'intera espressione tra parentesi e inserire l'operatore typecast all'inizio.