Java è un linguaggio di programmazione orientato agli oggetti che è stato il linguaggio principale dell'Android SDK per oltre un decennio. Nonostante la transizione ufficiale di Google verso Kotlin, Java rimane una parte importante dell'ecosistema: progetti legacy, applicazioni aziendali e milioni di righe di codice su Google Play continuano a funzionare su Java. Secondo il rapporto JetBrains Developer Ecosystem (2025), circa il 35% dei progetti Android utilizza ancora Java. Leggi di più sulle tendenze attuali nel rapporto ufficiale JetBrains.
Punti chiave
Java è un linguaggio di programmazione generico creato da Sun Microsystems nel 1995. Il principio principale è "Write Once, Run Anywhere": il bytecode Java compilato viene eseguito su qualsiasi piattaforma con la macchina virtuale JVM installata. Nel contesto dello sviluppo mobile, Java è diventato il primo linguaggio ufficiale dell'Android SDK, rilasciato da Google nel 2008.
L'architettura Java si basa su tre componenti: JDK (Java Development Kit) — set di strumenti per lo sviluppatore, JRE (Java Runtime Environment) — ambiente di esecuzione e JVM (Java Virtual Machine) — macchina virtuale. Android utilizza la propria implementazione JVM — Android Runtime (ART), che ha sostituito Dalvik nella versione 5.0 (Lollipop). ART esegue bytecode DEX, compilato dal bytecode Java tramite l'utilità dx/d8.
Una caratteristica fondamentale di Java è la gestione automatica della memoria tramite Garbage Collector (GC). Lo sviluppatore non deve liberare esplicitamente la memoria — il GC traccia gli oggetti inutilizzati e li rimuove. In Android ART vengono utilizzati Concurrent Mark Sweep (CMS) e Generational GC, ottimizzati per le risorse limitate dei dispositivi mobili. Questo riduce il carico dello sviluppatore, ma può causare "lag" durante la garbage collection sul thread UI.
Android supporta un sottoinsieme dell'API Java che si espande con ogni nuova versione del sistema operativo. Android 12 (API 31) ha aggiunto il supporto a Java 11, inclusi lambda con cattura di variabili, sistema modulare JPMS e client HTTP java.net.http. Android 14 (API 34) ha introdotto il supporto sperimentale per Java 17 tramite desugaring D8/R8 — alcune funzionalità (records, sealed classes) vengono tradotte in codice compatibile per le versioni precedenti.
| Versione Java | API Android (min) | Versione Android | Funzionalità chiave |
|---|---|---|---|
| Java 7 | API 19 | 4.4 KitKat | try-with-resources, multi-catch |
| Java 8 | API 24 | 7.0 Nougat | Lambda, Stream API, Optional |
| Java 11 | API 31 | 12 | HTTP Client, Local-Variable Syntax |
| Java 17 | API 34 | 14 | Records, Sealed Classes (D8) |
L'Android SDK include il compilatore Java, l'utilità dex (d8), aapt (Asset Packaging Tool), l'emulatore e le librerie android.* e java.*. Lo sviluppatore scrive codice in Java, lo compila in file .class (bytecode JVM), poi d8 li converte in file .dex (Dalvik Executable), che vengono impacchettati in APK insieme a risorse e AndroidManifest.xml.
Gradle è il sistema di build dei progetti Android. Il file build.gradle (Groovy) o build.gradle.kts (Kotlin DSL) descrive dipendenze, versioni SDK, flavor e firme. Android Gradle Plugin (AGP) versione 8.x automatizza il desugar — traduzione delle funzionalità Java moderne in codice compatibile all'indietro. Ad esempio, java.time.LocalDate viene convertito in codice compatibile con API 21+ senza modifiche nel codice sorgente dello sviluppatore.
// Activity Android semplice in Java
package com.example.myapp;
import android.os.Bundle;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = findViewById(R.id.textView);
tv.setText("Hello from Java!");
}
// Metodo per gestire il clic del pulsante
public void onButtonClick(View view) {
TextView tv = findViewById(R.id.textView);
tv.setText("Button clicked");
}
}La classe MainActivity estende AppCompatActivity — una classe base di AndroidX per la compatibilità all'indietro. Il metodo onCreate viene chiamato alla creazione dell'Activity; in esso viene impostato il layout tramite setContentView. findViewById collega una variabile Java a un elemento dal layout XML. Il metodo onButtonClick è legato al pulsante tramite l'attributo android:onClick in XML.
Il ciclo di vita dell'Activity in Java è una sequenza di callback: onCreate → onStart → onResume (attivo), onPause → onStop → onDestroy (terminazione). Lo sviluppatore sovrascrive questi metodi per gestire le risorse. onCreate — inizializzazione, onPause — salvataggio dati, onDestroy — rilascio risorse. Android chiama questi metodi durante la rotazione dello schermo, l'ingresso in background e la ricezione di una chiamata.
// Ciclo di vita dell'Activity con gestione dello stato
public class DetailActivity extends AppCompatActivity {
private String itemId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
itemId = getIntent().getStringExtra("ITEM_ID");
loadData(itemId);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("item_id", itemId);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
itemId = savedInstanceState.getString("item_id");
loadData(itemId);
}
private void loadData(String id) {
// Caricamento dati per identificatore
}
}Il metodo onSaveInstanceState salva lo stato dell'Activity durante la rotazione dello schermo o il cambio di attività. Bundle contiene coppie chiave-valore — tipi semplici, oggetti Parcelable o Serializable. onRestoreInstanceState ripristina lo stato salvato. Questo pattern è critico per Android, poiché il sistema può distruggere l'Activity in caso di memoria insufficiente e ripristinarla al ritorno dell'utente.
La sintassi Java è simile a C, fortemente tipizzata, orientata agli oggetti. Ogni file .java contiene una classe pubblica il cui nome corrisponde al nome del file. Java non supporta funzioni al di fuori delle classi — tutto è un metodo. Il punto di ingresso è il metodo statico public static void main(String[] args) per applicazioni console o i metodi del ciclo di vita dell'Activity Android per dispositivi mobili.
Java divide i tipi in primitivi (int, double, boolean, char, byte, short, long, float) e tipi di riferimento (classi, interfacce, array, enum). I primitivi sono memorizzati nello stack e passati per valore. Gli oggetti sono nell'heap, passati per riferimento. L'autoboxing converte automaticamente un primitivo in un oggetto wrapper (Integer, Double, Boolean), ma crea oggetti aggiuntivi — in Android questo è critico per le prestazioni dell'UI.
// Esempi di tipi di dati e strutture Java
public class DataTypes {
// Primitivi
int count = 42;
double price = 19.99;
boolean isActive = true;
char grade = 'A';
// Tipi di riferimento
String name = "Android";
Integer boxed = 100; // autoboxing
List<String> items = new ArrayList<>();
// Metodo con Generics
public <T> T getFirst(List<T> list) {
return list.isEmpty() ? null : list.get(0);
}
// Enum per insieme fisso di valori
public enum Status {
PENDING, LOADING, SUCCESS, ERROR
}
}I generici List<T> forniscono sicurezza dei tipi per le collection. Il metodo getFirst restituisce un elemento di qualsiasi tipo — il tipo specifico viene determinato nel punto di chiamata. Enum Status viene compilato in una classe con un insieme fisso di costanti, ogni istanza è un singleton. In Android, enum viene usato meno frequentemente a causa del consumo di memoria: ProGuard/R8 ottimizza enum in costanti int dove possibile.
Il confronto tra Java e Kotlin per lo sviluppo Android è stato uno dei temi principali dal 2019, quando Google ha dichiarato Kotlin il linguaggio prioritario. Kotlin è completamente compatibile con Java — entrambi compilano in bytecode JVM, possono chiamarsi a vicenda e usare le stesse librerie. Tuttavia, gli approcci alla scrittura del codice differiscono drasticamente.
Kotlin elimina la verbosità di Java: data class sostituisce 50+ righe di una classe Java con getter, setter, equals, hashCode, toString e copy. La sicurezza dei null è integrata nel sistema di tipi di Kotlin — NullPointerException è praticamente impossibile. Le funzioni di estensione consentono di aggiungere metodi a classi esistenti senza ereditarietà. Smart Casts convertono automaticamente i tipi dopo un controllo.
| aspetto | Java | Kotlin |
|---|---|---|
| Sicurezza null | Annotazioni @Nullable / @NonNull | String? / String — integrato |
| Data class | 50+ righe con Lombok | data class User(val name: String) |
| Estensione | Classi di utilità statiche | fun String.isEmail(): Boolean |
| Coroutine | AsyncTask / ExecutorService | suspend + Structured Concurrency |
| Lambda | FunctionalInterface + ::method | Lambda per impostazione predefinita |
| Annotazioni DI | @Inject, @Module, @Provides | Simili, ma meno codice |
In termini di prestazioni, Java e Kotlin sono identici — entrambi compilano in bytecode JVM, che Android ART esegue allo stesso modo. La differenza sta nella dimensione dell'APK: Kotlin aggiunge ~200-400 KB per la libreria kotlin-stdlib. I progetti Java hanno una dimensione APK inferiore grazie all'assenza di runtime aggiuntivo, ma utilizzando Java Stream API e Optional, la dimensione dell'APK può aumentare a causa del desugaring.
Gli strumenti dello sviluppatore Java per Android includono Android Studio, Gradle, il profiler e l'emulatore. Android Studio è l'IDE ufficiale, basato su IntelliJ IDEA Community, con editor di autocompletamento Java, analizzatore di codice (lint), refactoring e un editor visivo di layout (Layout Editor).
Android Gradle Plugin (AGP) versione 8.x gestisce il build: compilazione Java in classi, desugaring, minificazione ProGuard/R8, impacchettamento in APK/AAB. R8 è un desugaring e offuscatore aggiornato che sostituisce ProGuard. Le varianti di build (debug/release + product flavors) vengono configurate tramite build.gradle. Gradle Daemon accelera i build successivi tramite caching.
// build.gradle (app) — configurazione del modulo Java
android {
compileSdk 34
defaultConfig {
applicationId "com.example.myapp"
minSdk 21
targetSdk 34
versionCode 1
versionName "1.0"
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
testImplementation 'junit:junit:4.13.2'
}Il blocco compileOptions specifica la versione Java per la compilazione — Java 17 è disponibile con AGP 8.x. L'SDK minimo (minSdk) determina la versione minima di Android su cui l'applicazione funziona. Target SDK è la versione con cui l'applicazione è stata testata. La differenza tra compileSdk e targetSdk: compileSdk è l'API per la compilazione, targetSdk è il comportamento runtime.
Le limitazioni di Java in Android hanno portato alla transizione di Google verso Kotlin. NullPointerException è l'eccezione più comune nelle applicazioni Java Android, poiché il sistema di tipi non distingue tra riferimenti nullable e non-null. Google raccomanda le annotazioni @Nullable e @NonNull del pacchetto androidx.annotation, ma il compilatore non le verifica — solo lint lo fa.
L'assenza di coroutine è un'altra limitazione: le operazioni asincrone in Java richiedono callback, AsyncTask (deprecato da API 30), ExecutorService o RxJava. Questo porta a callback hell e perdite di memoria durante la rotazione dello schermo. Le coroutine di Kotlin con Structured Concurrency risolvono questo problema a livello di linguaggio: una coroutine viene annullata alla distruzione dell'Activity senza gestione manuale.
Il codice boilerplate in Java è una fonte di errori durante la scrittura manuale di equals/hashCode, implementazioni Parcelable e ViewHolder per RecyclerView. Le librerie Android KTX e Jetpack Compose sono orientate a Kotlin. Le nuove API Android (Room, Navigation, Compose) pubblicano esempi in Kotlin per impostazione predefinita, sebbene esistano versioni Java.
Domande frequenti
Java è un linguaggio di programmazione orientato agli oggetti di Sun Microsystems (1995), eseguito sulla macchina virtuale JVM. È stato il linguaggio principale dell'Android SDK fino al 2019. Viene utilizzato nello sviluppo mobile per progetti legacy, parte server (Spring) e applicazioni aziendali. Si caratterizza per tipizzazione forte, garbage collection automatica e multipiattaforma del bytecode.
Google ha dichiarato Kotlin come linguaggio prioritario per Android nel 2019. Le nuove librerie AndroidX, Jetpack Compose, le raccomandazioni sull'architettura e la documentazione vengono fornite per impostazione predefinita in Kotlin. Java rimane completamente supportato, ma le API sono progettate con un approccio Kotlin-first. I progetti Java richiedono più codice boilerplate e non ricevono per primi le nuove funzionalità linguistiche.
Android supporta completamente Java 8, Java 11 parzialmente da Android 12+ e Java 17 sperimentalmente tramite desugaring D8. Android Gradle Plugin (AGP) 8.x traduce il bytecode moderno in codice compatibile per API precedenti tramite desugar. Lo sviluppatore può scrivere in Java 11+, utilizzando lambda, Optional e DateTime API, ma records e sealed classes sono disponibili solo tramite D8.
Kotlin richiede meno codice: data class sostituisce decine di righe di boilerplate Java, la sicurezza dei null è integrata nei tipi, le coroutine semplificano l'asincrono. Java offre una sintassi più semplice per i principianti, un ecosistema di librerie collaudato e un tooling stabile. Le prestazioni runtime sono identiche — entrambi compilano in bytecode JVM eseguito da Android ART.
Android Studio è l'IDE standard per lo sviluppo Android con supporto per Java e Kotlin. Include emulatore, profiler (CPU, memoria, rete), Layout Inspector, APK Analyzer. IntelliJ IDEA è adatto per Java lato server. Eclipse ADT è obsoleto e non supportato da Google. Android Studio fornisce anche strumenti per migrare il codice Java in Kotlin tramite il convertitore integrato.
Riepilogo
Svilupperemo un'applicazione mobile chiavi in mano
IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.
Leggi anche