Tipi di Dato in Java
Java è un linguaggio fortemente tipizzato: ogni variabile deve avere un tipo dichiarato e il compilatore verifica che le operazioni siano compatibili con quel tipo. Questo previene molti errori a runtime.
Cosa Imparerai
- Tipi primitivi e loro range
- Variabili, costanti e scope
- Operatori aritmetici, logici e relazionali
- Strutture di controllo: if, switch, for, while
- Casting e conversioni di tipo
Tipi Primitivi
Java ha 8 tipi primitivi, suddivisi in 4 categorie: interi, decimali, caratteri e booleani.
Tipi Interi
// byte: 8 bit, da -128 a 127
byte etaStudente = 16;
byte maxVoto = 127;
// short: 16 bit, da -32,768 a 32,767
short annoNascita = 2008;
short giorniAnno = 365;
// int: 32 bit, da -2^31 a 2^31 - 1 (circa 2 miliardi)
int popolazioneClasse = 25;
int matricola = 123456789;
// long: 64 bit, per numeri molto grandi
long popolazioneMondiale = 8_000_000_000L; // nota la L finale
long millisecondiFondazione = 1704067200000L;
Tabella Riepilogativa
| Tipo | Bit | Range | Uso Tipico |
|---|---|---|---|
| byte | 8 | -128 a 127 | Voti, eta |
| short | 16 | -32,768 a 32,767 | Anni, giorni |
| int | 32 | circa ±2 miliardi | Contatori, ID |
| long | 64 | numeri molto grandi | Timestamp, popolazione |
Tipi Decimali (Floating Point)
// float: 32 bit, precisione singola (6-7 cifre)
float mediaVoti = 7.5f; // nota la f finale
float temperatura = 36.6f;
// double: 64 bit, precisione doppia (15-16 cifre)
double pi = 3.141592653589793;
double mediaMatematica = 8.25;
double percentualePromossi = 87.5;
Quando usare float vs double
- double: Default per decimali, più preciso
- float: Solo quando serve risparmiare memoria (grafica, giochi)
- Mai per soldi: Usa
BigDecimalper calcoli finanziari
Caratteri e Booleani
// char: 16 bit, un singolo carattere Unicode
char iniziale = 'M';
char votoLettera = 'A';
char simbolo = '€';
char unicode = '\u0041'; // 'A' in Unicode
// boolean: vero o falso
boolean isPromosso = true;
boolean haDebiti = false;
boolean maggiorenne = etaStudente >= 18;
Variabili e Costanti
Dichiarazione e Inizializzazione
// Dichiarazione
int voto;
// Inizializzazione
voto = 8;
// Dichiarazione e inizializzazione insieme
int altroVoto = 9;
// Dichiarazioni multiple
int italiano = 7, matematica = 8, storia = 6;
// var (Java 10+): inferenza di tipo
var nomeStudente = "Mario Rossi"; // inferisce String
var mediaClasse = 7.5; // inferisce double
Costanti con final
// Costanti: valore immutabile
final int VOTO_MASSIMO = 10;
final int VOTO_MINIMO = 1;
final double SOGLIA_PROMOZIONE = 6.0;
final String NOME_SCUOLA = "Liceo Einstein";
// Tentare di modificare una costante causa errore di compilazione
// VOTO_MASSIMO = 11; // ERRORE!
Scope delle Variabili
public class RegistroClasse {
// Variabile di istanza (visibile in tutta la classe)
private int numeroStudenti = 25;
public void stampaStatistiche() {
// Variabile locale (visibile solo nel metodo)
int sommaVoti = 0;
for (int i = 0; i < numeroStudenti; i++) {
// Variabile di blocco (visibile solo nel for)
int votoCorrente = ottieniVoto(i);
sommaVoti += votoCorrente;
}
// votoCorrente non e più accessibile qui!
double media = (double) sommaVoti / numeroStudenti;
System.out.println("Media: " + media);
}
}
Operatori
Operatori Aritmetici
int a = 10, b = 3;
int somma = a + b; // 13
int differenza = a - b; // 7
int prodotto = a * b; // 30
int quoziente = a / b; // 3 (divisione intera!)
int resto = a % b; // 1 (modulo)
// Divisione decimale
double quozienteReale = (double) a / b; // 3.333...
// Incremento e decremento
int voto = 7;
voto++; // 8 (post-incremento)
++voto; // 9 (pre-incremento)
voto--; // 8 (post-decremento)
// Operatori composti
voto += 2; // equivale a: voto = voto + 2
voto *= 2; // equivale a: voto = voto * 2
Operatori Relazionali
int voto = 7;
int sufficienza = 6;
boolean maggiore = voto > sufficienza; // true
boolean minore = voto < sufficienza; // false
boolean uguale = voto == sufficienza; // false
boolean diverso = voto != sufficienza; // true
boolean maggioreUguale = voto >= sufficienza; // true
boolean minoreUguale = voto <= sufficienza; // false
Operatori Logici
boolean sufficiente = voto >= 6;
boolean eccellente = voto >= 9;
boolean presente = true;
// AND logico (entrambe devono essere true)
boolean promuovibile = sufficiente && presente; // true
// OR logico (almeno una deve essere true)
boolean premiato = eccellente || presente; // true
// NOT logico (inverte il valore)
boolean assente = !presente; // false
// Short-circuit evaluation
// Se la prima condizione e false, la seconda non viene valutata
boolean risultato = false && metodoCostoso(); // metodoCostoso() non eseguito
Controllo del Flusso
if / else
int voto = 7;
// if semplice
if (voto >= 6) {
System.out.println("Promosso");
}
// if-else
if (voto >= 6) {
System.out.println("Promosso");
} else {
System.out.println("Bocciato");
}
// if-else if-else (valutazione voti scolastici)
if (voto >= 9) {
System.out.println("Eccellente");
} else if (voto >= 7) {
System.out.println("Buono");
} else if (voto >= 6) {
System.out.println("Sufficiente");
} else {
System.out.println("Insufficiente");
}
// Operatore ternario (if compatto)
String esito = voto >= 6 ? "Promosso" : "Bocciato";
switch
int mese = 9;
String nomeMese;
switch (mese) {
case 1:
nomeMese = "Gennaio";
break;
case 2:
nomeMese = "Febbraio";
break;
case 9:
nomeMese = "Settembre - Inizio scuola!";
break;
case 6:
case 7:
case 8:
nomeMese = "Vacanze estive";
break;
default:
nomeMese = "Altro mese";
}
// Sintassi moderna con arrow
String giudizio = switch (voto) {
case 10 -> "Ottimo";
case 9 -> "Distinto";
case 8 -> "Buono";
case 7 -> "Discreto";
case 6 -> "Sufficiente";
default -> "Insufficiente";
};
// Con blocchi
String descrizione = switch (voto) {
case 10, 9 -> {
System.out.println("Complimenti!");
yield "Eccellenza";
}
case 8, 7 -> "Buon rendimento";
default -> "Da migliorare";
};
Ciclo for
// for classico
System.out.println("Elenco studenti:");
for (int i = 1; i <= 5; i++) {
System.out.println("Studente " + i);
}
// for decrescente
System.out.println("Countdown:");
for (int i = 10; i >= 1; i--) {
System.out.println(i);
}
// for-each (enhanced for)
int[] voti = {7, 8, 6, 9, 8};
int somma = 0;
for (int v : voti) {
somma += v;
}
System.out.println("Somma voti: " + somma);
Ciclo while e do-while
// while: controlla PRIMA di eseguire
int tentativi = 0;
int votoMinimo = 6;
int votoOttenuto = 4;
while (votoOttenuto < votoMinimo && tentativi < 3) {
System.out.println("Tentativo " + (tentativi + 1));
votoOttenuto++; // simula miglioramento
tentativi++;
}
// do-while: esegue ALMENO UNA VOLTA
int risposta;
do {
System.out.println("Menu: 1=Voti, 2=Media, 0=Esci");
risposta = leggiInput();
} while (risposta != 0);
break e continue
// break: esce dal ciclo
int[] voti = {7, 8, 3, 9, 8};
for (int voto : voti) {
if (voto < 4) {
System.out.println("Trovato voto gravemente insufficiente!");
break; // esce dal ciclo
}
}
// continue: salta alla prossima iterazione
for (int voto : voti) {
if (voto < 6) {
continue; // salta i voti insufficienti
}
System.out.println("Voto sufficiente: " + voto);
}
Casting e Conversioni
// Widening (implicito): da tipo più piccolo a più grande
int votoIntero = 8;
double votoDouble = votoIntero; // 8.0 (automatico)
// Narrowing (esplicito): da tipo più grande a più piccolo
double media = 7.8;
int mediaIntera = (int) media; // 7 (troncamento, richiede cast)
// Attenzione all'overflow!
int grandeNumero = 130;
byte piccolo = (byte) grandeNumero; // -126 (overflow!)
// Conversione String -> numero
String votoStringa = "8";
int voto = Integer.parseInt(votoStringa);
double mediaDouble = Double.parseDouble("7.5");
// Conversione numero -> String
String risultato = String.valueOf(voto);
String altro = Integer.toString(voto);
String concatenato = "" + voto; // meno efficiente
Esempio Completo: Calcolo Pagella
package it.scuola.registro;
public class CalcoloPagella {
public static void main(String[] args) {
// Dati studente
final String NOME_STUDENTE = "Mario Rossi";
final String CLASSE = "3A";
// Voti per materia
int italiano = 7;
int matematica = 8;
int storia = 6;
int inglese = 9;
int scienze = 7;
// Array dei voti
int[] voti = {italiano, matematica, storia, inglese, scienze};
String[] materie = {"Italiano", "Matematica", "Storia", "Inglese", "Scienze"};
// Calcolo statistiche
int somma = 0;
int votoMax = voti[0];
int votoMin = voti[0];
int countSufficienti = 0;
for (int voto : voti) {
somma += voto;
if (voto > votoMax) votoMax = voto;
if (voto < votoMin) votoMin = voto;
if (voto >= 6) countSufficienti++;
}
double media = (double) somma / voti.length;
// Stampa pagella
System.out.println("╔════════════════════════════════════╗");
System.out.println("║ PAGELLA SCOLASTICA ║");
System.out.println("╠════════════════════════════════════╣");
System.out.printf("║ Studente: %-24s ║%n", NOME_STUDENTE);
System.out.printf("║ Classe: %-24s ║%n", CLASSE);
System.out.println("╠════════════════════════════════════╣");
for (int i = 0; i < materie.length; i++) {
String giudizio = switch (voti[i]) {
case 10, 9 -> "Eccellente";
case 8 -> "Buono";
case 7 -> "Discreto";
case 6 -> "Sufficiente";
default -> "Insufficiente";
};
System.out.printf("║ %-12s: %2d (%s)%n", materie[i], voti[i], giudizio);
}
System.out.println("╠════════════════════════════════════╣");
System.out.printf("║ Media: %.2f ║%n", media);
System.out.printf("║ Voto max: %d ║%n", votoMax);
System.out.printf("║ Voto min: %d ║%n", votoMin);
System.out.println("╠════════════════════════════════════╣");
// Esito finale
String esito;
if (countSufficienti == voti.length && media >= 6) {
esito = "PROMOSSO";
} else if (countSufficienti >= voti.length - 1) {
esito = "SOSPESO";
} else {
esito = "NON PROMOSSO";
}
System.out.printf("║ ESITO: %-27s ║%n", esito);
System.out.println("╚════════════════════════════════════╝");
}
}
Conclusione
In questo articolo abbiamo visto i tipi di dato primitivi di Java, le variabili e costanti, gli operatori e le strutture di controllo del flusso.
Nel prossimo articolo approfondiremo i metodi e le strutture dati base: come definire funzioni riutilizzabili e lavorare con gli array.
Punti Chiave da Ricordare
- 8 tipi primitivi: byte, short, int, long, float, double, char, boolean
- final: Rende una variabile costante
- Scope: Le variabili sono visibili solo nel loro blocco
- Switch expression: Java 14+ supporta la sintassi con arrow
- for-each: Preferibile quando non serve l'indice
- Casting: Necessario per conversioni narrowing







