Core Java: guía completa para dominar los fundamentos
Una guía detallada de los conceptos fundamentales de Java, desde las estructuras básicas hasta la programación orientada a objetos, con ejemplos prácticos para todos los niveles.
InSkillCoach
Core Java: guía completa para dominar los fundamentos
Java es uno de los lenguajes de programación más utilizados del mundo, especialmente valorado por su portabilidad, su robustez y su rico ecosistema. Esta guía te presenta los conceptos fundamentales de Core Java, desde lo más básico hasta las funcionalidades más avanzadas.
Introducción a Java
Java fue creado por James Gosling en Sun Microsystems (hoy Oracle) y se lanzó en 1995. Su filosofía “Write Once, Run Anywhere” (WORA) revolucionó el desarrollo de software.
Características principales
- Orientado a objetos: todo en Java es un objeto, salvo los tipos primitivos
- Independiente de la plataforma: gracias a la JVM (Java Virtual Machine)
- Robusto: gestión de errores sólida y comprobación de tipos en tiempo de compilación
- Seguro: ejecución en un entorno controlado (sandbox)
- Multihilo: soporte integrado para la programación concurrente
- Alto rendimiento: compilador JIT (Just-In-Time) que optimiza la ejecución
Instalación y configuración
Instalar el JDK (Java Development Kit)
# En Ubuntu/Debian
sudo apt update
sudo apt install openjdk-17-jdk
# En macOS con Homebrew
brew install openjdk@17
# En Windows
# Descargar desde https://www.oracle.com/java/technologies/downloads/
Configurar las variables de entorno
# En Linux/macOS
export JAVA_HOME=/path/to/jdk
export PATH=$PATH:$JAVA_HOME/bin
# En Windows
# Definir JAVA_HOME y añadir %JAVA_HOME%\bin al PATH
Primeros pasos con Java
Estructura básica de un programa Java
// Archivo: HelloWorld.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Compilar y ejecutar
# Compilar
javac HelloWorld.java
# Ejecutar
java HelloWorld
Tipos de datos y variables
Tipos primitivos
// Tipos numéricos enteros
byte b = 127; // 8 bits, de -128 a 127
short s = 32767; // 16 bits, de -32,768 a 32,767
int i = 2147483647; // 32 bits, de -2,147,483,648 a 2,147,483,647
long l = 9223372036854775807L; // 64 bits, rango muy amplio
// Tipos numéricos de coma flotante
float f = 3.14f; // 32 bits
double d = 3.14159; // 64 bits
// Otros tipos primitivos
char c = 'A'; // 16 bits, carácter Unicode
boolean bool = true; // true o false
Variables y constantes
// Declaración de variable
int nombre;
nombre = 42;
// Declaración e inicialización
String message = "Bonjour";
// Constantes (final)
final double PI = 3.14159;
Operadores
Operadores aritméticos
int a = 10, b = 3;
int somme = a + b; // 13
int difference = a - b; // 7
int produit = a * b; // 30
int quotient = a / b; // 3 (división entera)
int reste = a % b; // 1 (módulo)
// Incremento y decremento
a++; // a = a + 1
b--; // b = b - 1
Operadores de comparación
boolean egal = (a == b); // false
boolean different = (a != b); // true
boolean superieur = (a > b); // true
boolean inferieur = (a < b); // false
boolean supOuEgal = (a >= b); // true
boolean infOuEgal = (a <= b); // false
Operadores lógicos
boolean x = true, y = false;
boolean et = x && y; // false (AND lógico)
boolean ou = x || y; // true (OR lógico)
boolean non = !x; // false (NOT lógico)
Estructuras de control
Condiciones
// If-else
int age = 18;
if (age < 18) {
System.out.println("Mineur");
} else if (age == 18) {
System.out.println("Tout juste majeur");
} else {
System.out.println("Majeur");
}
// Switch
int jour = 3;
switch (jour) {
case 1:
System.out.println("Lundi");
break;
case 2:
System.out.println("Mardi");
break;
case 3:
System.out.println("Mercredi");
break;
// ...
default:
System.out.println("Jour inconnu");
}
// Expresión ternaria
String statut = (age >= 18) ? "Majeur" : "Mineur";
Bucles
// Bucle for
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
// Bucle while
int compteur = 0;
while (compteur < 5) {
System.out.println(compteur);
compteur++;
}
// Bucle do-while
int j = 0;
do {
System.out.println(j);
j++;
} while (j < 5);
// Bucle for-each (para colecciones)
int[] nombres = {1, 2, 3, 4, 5};
for (int nombre : nombres) {
System.out.println(nombre);
}
Arrays y colecciones
Arrays
// Declaración e inicialización de un array
int[] nombres = new int[5];
nombres[0] = 10;
nombres[1] = 20;
// Inicialización con valores
int[] valeurs = {10, 20, 30, 40, 50};
// Array multidimensional
int[][] matrice = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Recorrer un array
for (int i = 0; i < nombres.length; i++) {
System.out.println(nombres[i]);
}
Collections Framework
import java.util.*;
// Lista
List<String> liste = new ArrayList<>();
liste.add("Pomme");
liste.add("Banane");
liste.add("Orange");
System.out.println(liste.get(1)); // Banane
liste.remove("Pomme");
// Conjunto (elementos únicos)
Set<Integer> ensemble = new HashSet<>();
ensemble.add(1);
ensemble.add(2);
ensemble.add(1); // Se ignora porque ya está presente
System.out.println(ensemble.size()); // 2
// Map (clave-valor)
Map<String, Integer> map = new HashMap<>();
map.put("Pierre", 30);
map.put("Marie", 25);
System.out.println(map.get("Marie")); // 25
Programación orientada a objetos (POO)
Clases y objetos
// Definición de una clase
public class Personne {
// Atributos (campos)
private String nom;
private int age;
// Constructor
public Personne(String nom, int age) {
this.nom = nom;
this.age = age;
}
// Métodos
public void sePresenter() {
System.out.println("Je m'appelle " + nom + " et j'ai " + age + " ans.");
}
// Getters y Setters
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
// Uso de la clase
Personne personne = new Personne("Alice", 30);
personne.sePresenter();
personne.setAge(31);
System.out.println(personne.getAge()); // 31
Herencia
// Clase padre
public class Animal {
protected String nom;
public Animal(String nom) {
this.nom = nom;
}
public void manger() {
System.out.println(nom + " mange.");
}
}
// Clase hija
public class Chien extends Animal {
private String race;
public Chien(String nom, String race) {
super(nom); // Llamada al constructor padre
this.race = race;
}
public void aboyer() {
System.out.println(nom + " aboie.");
}
// Sobrescritura de método
@Override
public void manger() {
System.out.println(nom + " le chien mange des croquettes.");
}
}
// Uso
Chien rex = new Chien("Rex", "Berger Allemand");
rex.manger(); // "Rex le chien mange des croquettes."
rex.aboyer(); // "Rex aboie."
Polimorfismo
Animal animal1 = new Animal("Truc");
Animal animal2 = new Chien("Médor", "Labrador"); // Polimorfismo
animal1.manger(); // "Truc mange."
animal2.manger(); // "Médor le chien mange des croquettes."
// animal2.aboyer(); // Error de compilación, porque animal2 es de tipo Animal
((Chien) animal2).aboyer(); // OK tras el cast
Interfaces
// Definición de una interfaz
public interface Nageur {
void nager();
}
// Implementación de una interfaz
public class Poisson extends Animal implements Nageur {
public Poisson(String nom) {
super(nom);
}
@Override
public void nager() {
System.out.println(nom + " nage rapidement.");
}
}
// Implementación múltiple
public class Canard extends Animal implements Nageur {
public Canard(String nom) {
super(nom);
}
@Override
public void nager() {
System.out.println(nom + " nage lentement.");
}
}
// Uso
Nageur nageur1 = new Poisson("Nemo");
Nageur nageur2 = new Canard("Donald");
nageur1.nager(); // "Nemo nage rapidement."
nageur2.nager(); // "Donald nage lentement."
Clases abstractas
// Clase abstracta
public abstract class Vehicule {
protected String marque;
public Vehicule(String marque) {
this.marque = marque;
}
// Método concreto
public void demarrer() {
System.out.println("Le véhicule démarre.");
}
// Método abstracto (a implementar por las subclases)
public abstract void accelerer();
}
// Implementación de una clase abstracta
public class Voiture extends Vehicule {
public Voiture(String marque) {
super(marque);
}
@Override
public void accelerer() {
System.out.println("La voiture " + marque + " accélère.");
}
}
Gestión de excepciones
Try-catch-finally
try {
// Código susceptible de generar una excepción
int resultat = 10 / 0; // División por cero
} catch (ArithmeticException e) {
// Gestión de la excepción
System.out.println("Erreur: Division par zéro");
e.printStackTrace();
} finally {
// Código que se ejecuta en todos los casos
System.out.println("Fin du traitement");
}
Excepciones personalizadas
// Definición de una excepción personalizada
public class AgeInvalideException extends Exception {
public AgeInvalideException(String message) {
super(message);
}
}
// Uso
public class Utilisateur {
private String nom;
private int age;
public void setAge(int age) throws AgeInvalideException {
if (age < 0 || age > 150) {
throw new AgeInvalideException("L'âge doit être compris entre 0 et 150");
}
this.age = age;
}
}
// Gestión de la excepción
Utilisateur utilisateur = new Utilisateur();
try {
utilisateur.setAge(200);
} catch (AgeInvalideException e) {
System.out.println("Erreur: " + e.getMessage());
}
Entrada/Salida (I/O)
Lectura de archivos
import java.io.*;
// try-with-resources para el cierre automático
try (BufferedReader reader = new BufferedReader(new FileReader("fichier.txt"))) {
String ligne;
while ((ligne = reader.readLine()) != null) {
System.out.println(ligne);
}
} catch (IOException e) {
e.printStackTrace();
}
Escritura de archivos
try (BufferedWriter writer = new BufferedWriter(new FileWriter("sortie.txt"))) {
writer.write("Ligne 1");
writer.newLine();
writer.write("Ligne 2");
} catch (IOException e) {
e.printStackTrace();
}
Flujos de E/S
// Entrada por consola
try (Scanner scanner = new Scanner(System.in)) {
System.out.print("Entrez votre nom: ");
String nom = scanner.nextLine();
System.out.println("Bonjour, " + nom + "!");
}
// Salida con formato
System.out.printf("Température: %.1f°C%n", 22.5);
Genericidad
// Clase genérica
public class Boite<T> {
private T contenu;
public void mettre(T contenu) {
this.contenu = contenu;
}
public T prendre() {
return contenu;
}
}
// Uso
Boite<String> boiteTexte = new Boite<>();
boiteTexte.mettre("Hello");
String texte = boiteTexte.prendre();
Boite<Integer> boiteNombre = new Boite<>();
boiteNombre.mettre(42);
int nombre = boiteNombre.prendre();
Métodos genéricos
public <T> void afficherTableau(T[] tableau) {
for (T element : tableau) {
System.out.println(element);
}
}
// Uso
String[] mots = {"Bonjour", "le", "monde"};
Integer[] nombres = {1, 2, 3, 4, 5};
afficherTableau(mots);
afficherTableau(nombres);
Lambda y Streams (Java 8+)
Expresiones lambda
// Interfaz funcional
interface Calculateur {
int calculer(int a, int b);
}
// Enfoque tradicional
Calculateur addition = new Calculateur() {
@Override
public int calculer(int a, int b) {
return a + b;
}
};
// Con lambda
Calculateur additionLambda = (a, b) -> a + b;
System.out.println(additionLambda.calculer(5, 3)); // 8
// Otros ejemplos
Runnable tache = () -> System.out.println("Tâche exécutée");
Comparator<String> comparateur = (s1, s2) -> s1.length() - s2.length();
API Stream
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
List<String> noms = Arrays.asList("Jean", "Marie", "Pierre", "Sophie");
// Filtrado
List<String> nomsLongs = noms.stream()
.filter(nom -> nom.length() > 4)
.collect(Collectors.toList()); // [Marie, Pierre, Sophie]
// Mapping
List<Integer> longueurs = noms.stream()
.map(String::length)
.collect(Collectors.toList()); // [4, 5, 6, 6]
// Reducción
int somme = noms.stream()
.mapToInt(String::length)
.sum(); // 21
// Otras operaciones
boolean tousLongs = noms.stream().allMatch(nom -> nom.length() > 3); // true
String concatenation = noms.stream().collect(Collectors.joining(", ")); // "Jean, Marie, Pierre, Sophie"
Multithreading y concurrencia
Creación de hilos
// Método 1: extender Thread
class MonThread extends Thread {
@Override
public void run() {
System.out.println("MonThread s'exécute");
}
}
// Método 2: implementar Runnable
class MaTache implements Runnable {
@Override
public void run() {
System.out.println("MaTache s'exécute");
}
}
// Uso
Thread thread1 = new MonThread();
thread1.start();
Thread thread2 = new Thread(new MaTache());
thread2.start();
// Lambda con Runnable
Thread thread3 = new Thread(() -> {
System.out.println("Tâche lambda s'exécute");
});
thread3.start();
Sincronización
public class Compteur {
private int valeur = 0;
// Método sincronizado
public synchronized void incrementer() {
valeur++;
}
// Bloque sincronizado
public void incrementerBloc() {
synchronized(this) {
valeur++;
}
}
public int getValeur() {
return valeur;
}
}
ExecutorService
import java.util.concurrent.*;
// Creación de un pool de hilos
ExecutorService executor = Executors.newFixedThreadPool(5);
// Enviar tareas
executor.submit(() -> {
System.out.println("Tâche exécutée par " + Thread.currentThread().getName());
});
// Esperar a la terminación de todas las tareas
executor.shutdown();
executor.awaitTermination(5, TimeUnit.SECONDS);
Conclusión
Java es un lenguaje robusto y polivalente que ofrece una amplia gama de funcionalidades para desarrollar aplicaciones de calidad. Al dominar estos conceptos fundamentales, podrá:
- Crear aplicaciones completas y de alto rendimiento
- Comprender y utilizar el ecosistema Java (Spring, Hibernate, etc.)
- Desarrollar soluciones empresariales fiables y mantenibles
- Implementar arquitecturas de software modernas
Para ir más allá, explore los frameworks Java más populares como Spring Boot, la programación reactiva con Project Reactor o RxJava, y las API más recientes como los módulos (Java 9+) y los records (Java 16+).
Acerca de InSkillCoach
Experto en formación y tecnologías
Coach especializado en tecnologías avanzadas e IA, impulsado por GNeurone Inc.
Certificaciones:
- AWS Certified Solutions Architect – Professional
- Certificaciones de Google Cloud
- Microsoft Certified: DevOps Engineer Expert
- Certified Kubernetes Administrator (CKA)
- CompTIA Security+
Comentarios
Los comentarios funcionan con GitHub Discussions
Inicia sesión con GitHub para participar en la discusión