Programación · Lenguajes de programación
Tutorial de Java para principiantes
Respuesta corta
Java es un lenguaje orientado a objetos de tipado estático que se compila a bytecode y se ejecuta en la Java Virtual Machine (JVM) en cualquier sistema operativo. Instala un JDK, guarda una clase en Hello.java y ejecuta java Hello.java. Las ideas centrales son las clases y los objetos, los tipos primitivos y de referencia, el framework de colecciones (List, Map, Set), las excepciones comprobadas y novedades como los records, var y el pattern matching.
Qué es Java y para qué se usa
Java fue lanzado por Sun Microsystems en 1995 y hoy se desarrolla en el proyecto abierto OpenJDK, con Oracle como principal responsable. Su promesa es «escribe una vez, ejecuta en cualquier parte»: el compilador genera bytecode y la JVM lo ejecuta en Windows, macOS y Linux. Java se usa en grandes back ends empresariales (a menudo con Spring Boot), aplicaciones Android (junto con Kotlin), herramientas de big data como Apache Kafka y Hadoop, y muchos sistemas de escritorio y embebidos. Cada seis meses sale una versión nueva, y las versiones de soporte a largo plazo (LTS), como Java 21, son la opción habitual en producción.
Instalar un JDK y ejecutar Hello, world
Instala un JDK (Java Development Kit), por ejemplo una compilación de OpenJDK como Eclipse Temurin o el JDK de Oracle. Compruébalo con java -version. Todo programa Java vive dentro de una clase y la ejecución empieza en main.
public class Hello {
public static void main(String[] args) {
System.out.println("Hello, world");
}
}java Hello.java # run a single source file directly
# Hello, world
javac Hello.java # or compile to Hello.class first
java HelloEl nombre del archivo debe coincidir con el de la clase pública (Hello.java para class Hello).
Variables y tipos básicos
Java tiene ocho tipos primitivos, que almacenan el valor directamente, y tipos de referencia (objetos como String y los arrays). Cada variable tiene un tipo fijo; var permite que el compilador lo infiera del valor inicial dentro de los métodos.
| Tipo | Tamaño | Ejemplo |
|---|---|---|
int | 32 bits | int n = 42; |
long | 64 bits | long big = 10_000_000_000L; |
double | float de 64 bits | double pi = 3.14159; |
boolean | verdadero/falso | boolean ok = true; |
char | unidad UTF-16 de 16 bits | char c = 'A'; |
byte, short, float | 8, 16, 32 bits | Se usan menos |
String | referencia | String s = "hi"; |
int count = 7;
double avg = count / 2; // 3.0, integer division happens first
double avg2 = count / 2.0; // 3.5
var name = "Ada"; // inferred as String
String msg = name + " has " + count + " items";
System.out.println(msg); // Ada has 7 items
System.out.println(Integer.parseInt("12") + 1); // 13Esto es un fragmento: coloca instrucciones como estas dentro de un método como main.
Control de flujo
int score = 72;
if (score >= 90) {
System.out.println("A");
} else if (score >= 70) {
System.out.println("B"); // B
} else {
System.out.println("C");
}
for (int i = 0; i < 3; i++) {
System.out.println(i); // 0, 1, 2
}
String day = "SAT";
String kind = switch (day) { // switch expression
case "SAT", "SUN" -> "weekend";
default -> "weekday";
};
System.out.println(kind); // weekendJava también tiene while, do/while y el bucle for (String s : list) mejorado para recorrer arrays y colecciones.
Métodos, clases y records
Una clase agrupa campos (datos) y métodos (comportamiento). Los métodos static pertenecen a la propia clase; los demás se llaman sobre un objeto creado con new. Un record es una forma corta de declarar una clase de datos inmutable: el compilador genera el constructor, los accesores, equals, hashCode y toString.
public class Shapes {
static double square(double x) {
return x * x;
}
static class Counter {
private int value;
void increment() { value++; }
int get() { return value; }
}
record Point(int x, int y) {
double distance() { return Math.sqrt(x * x + y * y); }
}
public static void main(String[] args) {
System.out.println(square(4)); // 16.0
Counter c = new Counter();
c.increment();
c.increment();
System.out.println(c.get()); // 2
Point p = new Point(3, 4);
System.out.println(p + " " + p.distance()); // Point[x=3, y=4] 5.0
}
}Las clases pueden extender una sola clase padre (extends) e implementar muchas interfaces (implements). Los campos suelen ser private, con acceso mediante métodos.
Colecciones: List, Map y Set
El framework de colecciones de java.util ofrece estructuras de datos redimensionables. Las colecciones guardan objetos, así que los primitivos se encapsulan automáticamente (int pasa a Integer).
import java.util.*;
public class Collections101 {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>(List.of(3, 1, 2));
nums.add(5);
Collections.sort(nums);
System.out.println(nums + " " + nums.get(0)); // [1, 2, 3, 5] 1
Map<String, Integer> ages = new HashMap<>();
ages.put("ann", 31);
ages.put("bob", 25);
System.out.println(ages.getOrDefault("zed", 0)); // 0
Set<String> tags = new TreeSet<>(List.of("b", "a", "b"));
System.out.println(tags); // [a, b]
List<Integer> evensSquared = nums.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * n)
.toList();
System.out.println(evensSquared); // [4]
}
}La última instrucción usa streams y lambdas, un estilo funcional para transformar colecciones. List.of crea una lista inmutable; envuélvela en new ArrayList<>(...) cuando necesites modificarla.
Características distintivas: tipado estático, interfaces y pattern matching
Las interfaces definen un contrato que muchas clases pueden implementar, y son la base de la mayoría del diseño en Java. El Java moderno añade pattern matching: instanceof y switch pueden comprobar un tipo y enlazar una variable en un solo paso. Las interfaces selladas (Java 17 y posteriores) enumeran todas las implementaciones permitidas, de modo que el compilador puede comprobar que un switch cubre todos los casos.
public class Areas {
sealed interface Shape permits Circle, Rect {}
record Circle(double r) implements Shape {}
record Rect(double w, double h) implements Shape {}
static double area(Shape s) {
return switch (s) {
case Circle c -> Math.PI * c.r() * c.r();
case Rect r -> r.w() * r.h();
};
}
public static void main(String[] args) {
System.out.println(area(new Rect(2, 3))); // 6.0
}
}El pattern matching en switch como este es estándar en Java 21 LTS y posteriores.
Excepciones
Los errores son excepciones. Las excepciones comprobadas (como IOException) deben capturarse o declararse con throws; las no comprobadas (subclases de RuntimeException, como NullPointerException) no hace falta. try-with-resources cierra archivos y conexiones automáticamente.
import java.io.*;
import java.nio.file.*;
public class ReadFirst {
static int parseAge(String text) {
int age = Integer.parseInt(text); // may throw NumberFormatException
if (age < 0) throw new IllegalArgumentException("negative age");
return age;
}
public static void main(String[] args) {
try {
System.out.println(parseAge("abc"));
} catch (NumberFormatException e) {
System.out.println("not a number"); // not a number
}
try (BufferedReader in = Files.newBufferedReader(Path.of("notes.txt"))) {
System.out.println(in.readLine());
} catch (IOException e) {
System.out.println("cannot read: " + e.getMessage());
}
}
}Un programa completo pequeño: contador de palabras
import java.io.IOException;
import java.nio.file.*;
import java.util.*;
public class WordCount {
public static void main(String[] args) throws IOException {
if (args.length != 1) {
System.err.println("usage: java WordCount.java FILE");
System.exit(1);
}
String text = Files.readString(Path.of(args[0])).toLowerCase();
Map<String, Integer> counts = new HashMap<>();
for (String word : text.split("[^a-z']+")) {
if (!word.isEmpty()) counts.merge(word, 1, Integer::sum);
}
counts.entrySet().stream()
.sorted(Map.Entry.<String, Integer>comparingByValue().reversed())
.limit(5)
.forEach(e -> System.out.printf("%5d %s%n", e.getValue(), e.getKey()));
}
}Ejecútalo con java WordCount.java notes.txt. Imprime las cinco palabras más frecuentes con su número de apariciones.
Errores comunes de principiantes
- División entera:
5 / 2es2. Haz que un lado seadoublepara obtener2.5. NullPointerExceptionpor llamar a un método sobrenull. Comprueba si esnullo usaOptionalpara valores que pueden faltar.- Intentar modificar una lista creada con
List.of, lo que lanzaUnsupportedOperationException. - Olvidar que los índices de arrays y de
Listempiezan en 0, por lo que el último elemento está enlength - 1.
Adónde ir después
Sigue las rutas de aprendizaje de dev.java, el sitio oficial para desarrolladores Java, y ten a mano la documentación de la API de Java SE como referencia. Aprende una herramienta de compilación (Maven o Gradle), pruebas unitarias con JUnit y después un framework como Spring Boot para servicios web. Kotlin, que también se ejecuta en la JVM, es un siguiente lenguaje natural.
Preguntas frecuentes
¿Es difícil aprender Java?
Java es más verboso que Python, porque hay que declarar tipos y poner el código en clases, pero sus reglas son coherentes y el compilador explica los errores pronto. Muchas universidades lo usan como primer lenguaje.
¿Cuál es la diferencia entre el JDK y la JVM?
La JVM ejecuta bytecode ya compilado. El JDK es el kit de desarrollo completo: la JVM más el compilador javac, la biblioteca estándar y herramientas. Los desarrolladores instalan el JDK.
¿Qué versión de Java debo aprender?
Aprende una versión actual de soporte a largo plazo, como Java 21 o una LTS más reciente. El código antiguo sigue funcionando en JVM nuevas, así que lo que aprendas hoy también sirve para proyectos existentes.
¿Java es lo mismo que JavaScript?
No. Aunque los nombres se parecen, son lenguajes distintos, con sistemas de tipos, entornos de ejecución y usos diferentes.
¿Se sigue usando Java?
Sí. Sigue siendo uno de los lenguajes más usados en back ends empresariales, Android e infraestructura de datos.