0%
Core Java: guía completa para dominar los fundamentos

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.

I

InSkillCoach

· min

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+).

InSkillCoach

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+
1.0k
122

Comentarios

Los comentarios funcionan con GitHub Discussions

Inicia sesión con GitHub para participar en la discusión

¡Enlace copiado!