1. Tipografia
Le variabili di tipi primitivi (con l'eccezione del boolean
tipo) 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:
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
, short
e byte
le variabili possono essere facilmente assegnate alle long
variabili. short
e byte
le variabili possono essere assegnate alle int
variabili. E byte
le variabili possono essere assegnate alle short
variabili.
Esempi:
Codice | Descrizione |
---|---|
|
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 |
float
le variabili possono essere assegnate alle double
variabili senza problemi. Ma le cose sono più interessanti con i tipi interi.
È possibile assegnare qualsiasi variabile intera a una float
variabile. Anche il long
tipo, che è lungo 8 byte. E puoi assegnare quello che vuoi - qualsiasi variabile o float
variabile intera - a una double
variabile:
Codice | Nota |
---|---|
|
|
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 long
valore a una int
variabile?
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 |
---|---|
|
Ogni volta l'operatore typecast deve essere indicato in modo esplicito |
Qui a
è uguale a 1
e forse l'operatore typecast sembra eccessivo. Ma se a
fossero più grandi?
Codice | Descrizione |
---|---|
|
|
Un milione si inserisce perfettamente in a long
e in an int
. Ma quando si assegna un milione a una short
variabile, 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 |
char
tipo
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 short
tipo è firmato e può contenere valori da -32,768
a +32,767
, ma il char
tipo non è firmato e può contenere valori da 0
a 65,535
.
I numeri negativi non possono essere memorizzati in a char
, ma possono essere memorizzati in a short
. E a short
non 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 int
e a long
sono coinvolti in un'espressione, il valore di int
sarà convertito in a long
e solo allora l'operazione procederà:
Codice | Descrizione |
---|---|
|
a verrà ampliato in a long e quindi si verificherà l'addizione. |
Numeri in virgola mobile
Se un numero intero e un numero in virgola mobile ( float
o double
) sono coinvolti in un'espressione, il numero intero verrà convertito in un numero in virgola mobile ( float
o double
) e solo allora verrà eseguita l'operazione.
Se l'operazione coinvolge a float
e a double
, verrà float
convertito in a double
. Che in realtà è previsto.
I tipi byte
, short
e char
vengono sempre convertiti in int
quando interagiscono tra loro. C'è una buona ragione per cui il int
tipo è considerato il tipo intero standard.
Se moltiplichi a byte
per a short
ottieni un int
. Se moltiplichi a byte
per a byte
ottieni un int
. Anche se aggiungi a byte
e a byte
, ottieni un int
.
Ci sono diverse ragioni per questo. Esempi:
Codice | Descrizione |
---|---|
|
110 * 120 is 13,200 , che è leggermente maggiore del valore massimo del byte tipo:127 |
|
110 + 120 is 230 , anch'esso leggermente maggiore del valore massimo del byte tipo: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 int
vengono sempre immediatamente convertite in int
s. 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 |
---|---|
|
L' byte * byte espressione sarà unint |
|
L' byte + byte espressione sarà unint |
|
L' byte + int espressione 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 |
---|---|
|
L'operatore typecast verrà applicato solo alla a variabile, che è già un file byte . Questo codice non verrà compilato. |
|
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.