☕ Java: Potencia, portabilidad y ecosistema empresarial
Guía extensa y profunda — desde los cimientos hasta Java 21 (LTS), programación orientada a objetos, multihilo, colecciones, JavaFX, Spring y mucho más.
📖 Tabla de contenidos completa
- 1. ¿Qué es Java?
- 2. Historia y evolución (Java 8 a Java 21)
- 3. Sintaxis básica y Hola Mundo
- 4. Variables, tipos primitivos y envoltorios
- 5. Estructuras de control
- 6. Programación Orientada a Objetos
- 7. Clases y objetos avanzados
- 8. Collections Framework
- 9. Manejo de excepciones
- 10. Genéricos y tipos parametrizados
- 11. Lambdas y Stream API (Java 8+)
- 12. Concurrencia y multihilo
- 13. Entrada/Salida y NIO
- 14. Java 9+ (módulos, var, records)
- 15. Frameworks y ecosistema (Spring, Maven)
- 16. Buenas prácticas y estándares
🚀 1. ¿Qué es Java?
Java es un lenguaje de programación de alto nivel, orientado a objetos, basado en clases y diseñado para tener el menor número posible de dependencias de implementación. Fue creado por James Gosling en Sun Microsystems (ahora Oracle) y lanzado en 1995. Su lema "Write Once, Run Anywhere" se debe a la Java Virtual Machine (JVM), que permite ejecutar el mismo bytecode en cualquier plataforma. Java es el pilar de aplicaciones empresariales, Android (aunque con Kotlin en auge), sistemas financieros, big data (Hadoop, Spark) y aplicaciones web de misión crítica.
📜 2. Evolución de Java: desde Java 8 hasta Java 21 LTS
Java ha evolucionado con versiones cada 6 meses, pero las LTS (Long Term Support) son las más usadas: Java 8, 11, 17 y 21. Java 8 trajo lambdas y Stream API. Java 11 introdujo el cliente HTTP y mejoras. Java 17 aportó sellados (sealed classes) y pattern matching. Java 21 (LTS 2023) incluye Virtual Threads (Project Loom), Record Patterns, String Templates (preview), entre otros.
| Versión | Características clave |
|---|---|
| Java 8 (LTS) | Lambdas, Stream API, Optional, nueva API de fecha/hora (java.time), métodos default en interfaces. |
| Java 9 | Sistema de módulos (Project Jigsaw), JShell, métodos privados en interfaces. |
| Java 11 (LTS) | Cliente HTTP estándar, ejecución de archivos .java sin compilar, mejoras en colecciones. |
| Java 17 (LTS) | Sealed classes, pattern matching para switch, registros mejorados, text blocks. |
| Java 21 (LTS) | Virtual Threads, Record Patterns, Pattern Matching para switch completo, String Templates (preview). |
✏️ 3. Sintaxis fundamental y "Hola Mundo"
Un programa en Java requiere una clase y un método public static void main(String[] args). La compilación genera bytecode (.class) que ejecuta la JVM.
// HolaMundo.java
public class HolaMundo {
public static void main(String[] args) {
System.out.println("¡Hola, Java en Blogger!");
// Comentario de línea
/*
Comentario multilínea
*/
}
}
Compilación: javac HolaMundo.java → Ejecución: java HolaMundo
📦 4. Variables, tipos primitivos y wrappers
Tipos primitivos: byte, short, int, long, float, double, char, boolean. Cada uno tiene su clase envoltorio: Integer, Double, Character, etc. Java también tiene inferencia de tipos con var (desde Java 10).
public class Tipos {
public static void main(String[] args) {
int entero = 42;
double pi = 3.1415926535;
char letra = 'J';
boolean activo = true;
var mensaje = "Java moderno"; // inferido a String
final int DIAS_SEMANA = 7; // constante
Integer envoltorio = Integer.valueOf(100);
System.out.println(entero + ", " + pi + ", " + mensaje);
}
}
🔄 5. Estructuras de control
Condicionales: if-else, switch (con soporte para patrones desde Java 17). Bucles: for, for-each, while, do-while.
int nota = 85;
if (nota >= 90) {
System.out.println("Sobresaliente");
} else if (nota >= 70) {
System.out.println("Notable");
} else {
System.out.println("Mejorable");
}
// Switch mejorado (Java 14+)
String dia = "LUNES";
switch (dia) {
case "LUNES", "MARTES", "MIERCOLES" -> System.out.println("Entresemana");
default -> System.out.println("Fin de semana");
}
// for-each con array
int[] numeros = {1,2,3,4,5};
for (int n : numeros) {
System.out.print(n + " ");
}
🧬 6. POO en Java: clases, herencia, polimorfismo
Java es puramente orientado a objetos (excepto primitivos). Soporta encapsulación (public, private, protected), herencia simple (extends), polimorfismo mediante overriding y sobrecarga, abstracción con clases abstractas e interfaces.
// Interfaz y clase abstracta
interface Volador {
void volar();
}
abstract class Animal {
protected String nombre;
public Animal(String nombre) { this.nombre = nombre; }
public abstract void sonido();
}
class Ave extends Animal implements Volador {
public Ave(String nombre) { super(nombre); }
@Override
public void sonido() { System.out.println("Pío pío"); }
@Override
public void volar() { System.out.println(nombre + " está volando"); }
}
public class DemoPOO {
public static void main(String[] args) {
Ave pajarito = new Ave("Loro");
pajarito.sonido();
pajarito.volar();
}
}
🏗️ 7. Clases avanzadas: records, enumerados, clases anidadas
Records (Java 14+): clases inmutables para transportar datos. Enums: constantes tipadas. Clases anidadas (estáticas e internas).
// Record (inmutable)
record Persona(String nombre, int edad) {}
// Enum
enum Dia { LUNES, MARTES, MIERCOLES, JUEVES, VIERNES }
public class DemoAvanzado {
public static void main(String[] args) {
Persona p = new Persona("Ana", 28);
System.out.println(p.nombre() + ", " + p.edad());
for (Dia d : Dia.values()) {
System.out.println(d);
}
}
}
📚 8. Java Collections Framework
Interfaces principales: List, Set, Queue, Deque, Map. Implementaciones comunes: ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap, PriorityQueue.
import java.util.*;
public class Colecciones {
public static void main(String[] args) {
List<String> lista = new ArrayList<>();
lista.add("Java");
lista.add("Python");
lista.add("C++");
Collections.sort(lista);
Set<Integer> set = new HashSet<>(Arrays.asList(1,2,3,2,1));
Map<String, Integer> mapa = new HashMap<>();
mapa.put("A", 1);
mapa.put("B", 2);
// Iteración moderna
lista.forEach(System.out::println);
mapa.forEach((k,v) -> System.out.println(k + " -> " + v));
}
}
⚠️ 9. Manejo de excepciones
Excepciones checked (IOException) y unchecked (RuntimeException). Uso de try-catch-finally y try-with-resources (AutoCloseable).
import java.io.*;
public class Excepciones {
public static int division(int a, int b) throws ArithmeticException {
if (b == 0) throw new ArithmeticException("División por cero");
return a / b;
}
public static void main(String[] args) {
try {
int res = division(10, 0);
} catch (ArithmeticException e) {
System.err.println("Error: " + e.getMessage());
} finally {
System.out.println("Bloque finally ejecutado");
}
// try-with-resources
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String linea = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
}
}
📌 10. Genéricos (type safety)
Permiten escribir clases y métodos parametrizados por tipo. Ejemplo: List<String>. Evitan conversiones explícitas y mejoran la seguridad.
public class Caja<T> {
private T contenido;
public void set(T t) { this.contenido = t; }
public T get() { return contenido; }
public static <U> void imprimir(U valor) {
System.out.println(valor);
}
public static void main(String[] args) {
Caja<Integer> cajaInt = new Caja<>();
cajaInt.set(123);
Integer num = cajaInt.get();
Caja.imprimir("Texto genérico");
}
}
✨ 11. Lambdas y Stream API (Java 8+)
Expresiones lambda permiten programación funcional. Stream API opera sobre colecciones de forma declarativa, con operaciones intermedias y terminales.
import java.util.*;
import java.util.stream.*;
public class LambdasStreams {
public static void main(String[] args) {
List<Integer> numeros = Arrays.asList(1, 2, 3, 4, 5);
// Lambda
numeros.forEach(n -> System.out.print(n + " "));
// Stream: filtrar pares y multiplicar por 2
List<Integer> resultado = numeros.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.collect(Collectors.toList());
System.out.println("\nResultado: " + resultado);
// Optional
Optional<Integer> primero = numeros.stream().findFirst();
primero.ifPresent(System.out::println);
}
}
🧵 12. Concurrencia: hilos y ejecutores
Java soporta multihilo mediante Thread y Runnable. El paquete java.util.concurrent ofrece ExecutorService, futures, locks y colecciones concurrentes. Java 21 introduce Virtual Threads (Project Loom).
import java.util.concurrent.*;
public class Concurrencia {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// Usando ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(2);
Future<Integer> future = executor.submit(() -> {
Thread.sleep(1000);
return 42;
});
System.out.println("Resultado: " + future.get());
executor.shutdown();
// Virtual Thread (Java 21+)
// Thread.startVirtualThread(() -> System.out.println("Hilo virtual"));
}
}
💾 13. E/S tradicional y NIO (New I/O)
Paquete java.io para flujos de bytes y caracteres. java.nio ofrece buffers, canales y selectores para operaciones no bloqueantes.
import java.nio.file.*;
import java.io.*;
public class IOEjemplo {
public static void main(String[] args) throws IOException {
// Leer archivo con Files (NIO)
String contenido = Files.readString(Path.of("archivo.txt"));
System.out.println(contenido);
// Escribir con BufferedWriter
try (BufferedWriter bw = new BufferedWriter(new FileWriter("salida.txt"))) {
bw.write("Texto de ejemplo");
}
}
}
📦 14. Java 9+: Módulos, var, text blocks y más
- Módulos (Project Jigsaw): module-info.java encapsula paquetes.
- Text blocks (Java 15): """ ... """ para cadenas multilínea.
- Switch expressions (Java 14): -> y yield.
- Pattern matching para instanceof (Java 16).
- Sealed classes (Java 17): restringe herencia.
// Text block
String json = """
{
"nombre": "Java",
"version": 21
}
""";
System.out.println(json);
// Pattern matching instanceof
Object obj = "Cadena";
if (obj instanceof String s && s.length() > 0) {
System.out.println(s.toUpperCase());
}
🏭 15. Frameworks y herramientas imprescindibles
Spring Framework (Spring Boot): el estándar para microservicios y aplicaciones empresariales. Hibernate para ORM. Maven/Gradle para gestión de dependencias y construcción. Jakarta EE para aplicaciones corporativas. Android SDK para desarrollo móvil.
| Herramienta | Descripción |
|---|---|
| Maven | Gestión de dependencias y ciclo de vida (pom.xml) |
| Gradle | Automatización flexible, usado en Android |
| Spring Boot | Microservicios, configuración automática |
| JUnit 5 | Pruebas unitarias |
| IntelliJ IDEA / Eclipse | IDEs más populares |
✅ 16. Buenas prácticas y convenciones
- Seguir la convención de nombres: PascalCase para clases, camelCase para métodos y variables, constantes en MAYÚSCULAS.
- Programar contra interfaces, no contra implementaciones.
- Usar try-with-resources para recursos externos.
- Evitar null cuando sea posible; usar Optional.
- Aplicar el principio de responsabilidad única y mantener métodos pequeños.
- Documentar con Javadoc las APIs públicas.
- Escribir pruebas unitarias (JUnit) y pruebas de integración.
- Usar un linter como SpotBugs o SonarQube.
0 Comentarios