Introduction to the Java 21 SE language.

Advertisement
Contents of the article disguise

1. Introduction

1.1. What is Java?

Java is a general-purpose, object-oriented programming language designed to be highly portable. With the motto "write once, run anywhere," Java allows you to develop applications that run on multiple platforms without having to recompile the code. This feature has made Java a mainstay of software development in both the business world and academia and emerging technology.

1.2. Brief History and Impact on Computing

Since its introduction in 1995, Java has evolved to become one of the most popular programming languages. Originally developed by Sun Microsystems, its Java Virtual Machine (JVM)-based architecture has enabled complex applications to run with high performance and security on a variety of devices, from servers to mobile devices. Its impact on the internet, the creation of robust frameworks, and its continued evolution make it a benchmark for secure and scalable development in 2025.

2. Fundamental Java Concepts

2.1. The Origins of Java

Born in a context where the need for interoperability was high, Java was designed to offer security, portability, and a clear syntax derived from languages like C and C++. Its creation drove a shift in application development for the internet and embedded devices, marking the beginning of a new era in computing.

2.2. Relationship with C, C++ and C#

Although Java shares a similar syntax with C and C++, its foundation focuses on avoiding common problems in these languages, such as manual memory management and the complexity of multiple inheritance. On the other hand, C# was partly inspired by Java and has made competing design decisions; however, Java has distinguished itself with its "platform-neutral" philosophy and a very active developer community.

2.3. Java's Contribution to the Internet

Java revolutionized web application development with its ability to compile to bytecode, allowing the same code to run on any device with a JVM installed. This feature has been integral to the growth of server-side applications, web security, and mobile application development.

3. Evolution of the Java Language

3.1. History of the Java Language

From its first version in the 1990s to the arrival of Java 21, the language has undergone numerous iterations. Each update has introduced improvements in performance, syntax, and functionality, adapting to the needs of both business programming and new technological trends.

3.2. The Role of Java in Computing in 2025

Java remains essential in 2025, being used in critical applications in finance, telecommunications, embedded systems, and high-availability web services. Three pillars stand out:

3.2.1. Security

The JVM's robust architecture and strict resource access control in Java provide a secure environment against vulnerabilities. The inclusion of mechanisms such as sandboxing and code-level security policies make Java one of the most reliable languages for sensitive applications.

3.2.2. Portability

The generated bytecode allows Java code to run on any operating system that has the JVM installed, making migration between platforms almost transparent.

3.2.3. The Magic of Bytecode

The Java compilation process transforms source code into bytecode—a set of instructions interpreted by the JVM—enabling hardware independence and runtime optimization, ensuring competitive performance and high scalability.

4. Terminology and Paradigms in Java

4.1. Object-Oriented Programming (OOP)

The Object-Oriented Programming (OOP) It is a development paradigm that organizes code around objects, rather than independent functions and data. This approach allows for more intuitive modeling of systems, approximating the way humans think about the real world.

Java is a language that is designed from its foundations to work with OOP, making use of concepts such as encapsulation, inheritance, polymorphism, and abstraction, which allow the construction of modular, reusable and easy-to-maintain programs.

What is an object and what is a class?

In OOP, the objects represent instances of classes, which are structures that define the behavior and characteristics of a specific type of entity.

Simple example of a class and an object in Java:

// Definición de la clase Persona
public class Persona {
    String nombre;
    int edad;
    
    // Constructor de la clase
    public Persona(String nombre, int edad) {
        this.nombre = nombre;
        this.edad = edad;
    }

    // Método para mostrar información
    public void mostrarInfo() {
        System.out.println("Nombre: " + nombre + ", Edad: " + edad);
    }
}

// Clase principal con el método main
public class Main {
    public static void main(String[] args) {
        // Creación de un objeto de la clase Persona
        Persona persona1 = new Persona("Carlos", 30);
        persona1.mostrarInfo(); // Salida: Nombre: Carlos, Edad: 30
    }
}

In this example, the class Persona defines two attributes (nombre and edad), a builder and a method (mostrarInfo()). Then, in class Main, a is created object (persona1) and the method is called to display its information.

1. Encapsulation

The encapsulation It consists of hiding the internal details of an object and allowing access only through defined methods. This improves code security and modularity.

Example of encapsulation:

public class CuentaBancaria {
    private double saldo;  // Atributo privado, no accesible directamente

    // Constructor
    public CuentaBancaria(double saldoInicial) {
        saldo = saldoInicial;
    }

    // Método para depositar dinero
    public void depositar(double cantidad) {
        saldo += cantidad;
    }

    // Método para consultar el saldo
    public double consultarSaldo() {
        return saldo;
    }
}

// Uso en una clase principal
public class Banco {
    public static void main(String[] args) {
        CuentaBancaria cuenta = new CuentaBancaria(1000);
        cuenta.depositar(500);
        System.out.println("Saldo actual €: " + cuenta.consultarSaldo()); // Salida: 1500
    }
}

Here, the attribute saldo is private (private), which prevents direct access. Instead, public methods (depositar and consultarSaldo) to interact with it, which reinforces the security and integrity of the data.

2. Inheritance

The inheritance allows a class (subclase) get features from another class (superclase). This facilitates code reuse and class specialization.

Example of inheritance:

// Clase base
public class Animal {
    public void hacerSonido() {
        System.out.println("El animal hace un sonido");
    }
}

// Clase derivada (hereda de Animal)
public class Perro extends Animal {
    @Override
    public void hacerSonido() {
        System.out.println("El perro ladra");
    }
}

// Uso de herencia en el programa principal
public class Zoologico {
    public static void main(String[] args) {
        Animal miAnimal = new Animal();
        miAnimal.hacerSonido(); // Salida: El animal hace un sonido

        Perro miPerro = new Perro();
        miPerro.hacerSonido(); // Salida: El perro ladra
    }
}

The class Perro inherits of Animal, overwriting (@Override) the method hacerSonido(). Thanks to inheritance, Perro you can use the behavior of Animal and modify it according to your needs.

3. Polymorphism

He polymorphism allows the same method to be executed in different ways depending on the object that calls it. This is achieved through the overwrite (@Override) in inherited classes.

Example of polymorphism:

// Clase base
public class Vehiculo {
    public void acelerar() {
        System.out.println("El vehículo está acelerando.");
    }
}

// Clase derivada
public class Coche extends Vehiculo {
    @Override
    public void acelerar() {
        System.out.println("El coche acelera rápidamente.");
    }
}

// Otra clase derivada
public class Bicicleta extends Vehiculo {
    @Override
    public void acelerar() {
        System.out.println("La bicicleta avanza lentamente.");
    }
}

// Uso del polimorfismo en el programa
public class Carretera {
    public static void main(String[] args) {
        Vehiculo v1 = new Coche();
        Vehiculo v2 = new Bicicleta();

        v1.acelerar(); // Salida: El coche acelera rápidamente.
        v2.acelerar(); // Salida: La bicicleta avanza lentamente.
    }
}

Here, although v1 and v2 are declared as Vehiculo, at runtime each object executes its own version of the method acelerar(), showing the effect of polymorphism.

The Object-Oriented Programming (OOP) is fundamental in Java and allows you to create flexible, organized and reusable systems. By using encapsulation, inheritance and polymorphism, developers can design robust applications with less redundancy and greater code clarity.

In Java 21, the OOP paradigm continues to evolve with improvements such as Records, Sealed Classes and the implementation of more expressive patterns through Pattern Matching, which further enhances code security and maintainability.

4.2. Other Paradigms: Functional and Concurrent

Beyond OOP, Java has incorporated elements of functional programming into recent versions (e.g., lambdas and streams). Likewise, the evolution of the language in high-concurrency environments has led to the introduction of advanced tools such as Virtual Threads, which simplify and optimize the management of concurrent tasks.

5. Java 21: Features and What's New

5.1. New Features and Improvements

Java 21 brings a series of improvements that boost both performance and developer productivity. Key new features include:

  • Virtual Threads and Structured Concurrency: Facilitating the creation of lightweight threads and the management of multiple concurrent tasks in a more secure and scalable way.
  • Improved Records and Sealed Classes: These mechanisms allow you to create immutable classes and restrict inheritance to a controlled set of subclasses, improving the clarity and security of the design.
  • Pattern Matching for Switch: Syntax refinements that allow you to work with different data types in a more expressive and less error-prone manner.
  • Internal Optimizations and Better Memory Management: It provides performance improvements in high-demand scenarios, reducing resource management overhead.

5.2. Practical Examples in Java 21

Below are some code examples that illustrate the new features in Java SE 21 LTS:

Virtual Threads

public class VirtualThread {
    public static void main(String[] args) throws InterruptedException {
        // Creación y ejecución de un hilo virtual
        Thread virtualThread = Thread.ofVirtual().start(() -> {
            System.out.println("¡Hola desde un hilo virtual en Java 21!");
        });
        virtualThread.join();
    }
}

Sealed Classes and Records

// Definición de una interfaz sellada
public sealed interface Shape permits Circle, Rectangle {}

// Clase final que implementa Shape
public final class Circle implements Shape {
    private final double radius;
    
    public Circle(double radius) {
        this.radius = radius;
    }
    
    public double getRadius() {
        return radius;
    }
}

// Clase final para un rectángulo
public final class Rectangle implements Shape {
    private final double width;
    private final double height;
    
    public Rectangle(double width, double height) {
         this.width = width;
         this.height = height;
    }
    
    public double getWidth() {
         return width;
    }
    
    public double getHeight() {
         return height;
    }
}

// Uso de un record para representar un punto
public record Point(int x, int y) {}

Pattern Matching on Switch

public String getShapeName(Shape shape) {
    return switch (shape) {
        case Circle c -> "Círculo";
        case Rectangle r -> "Rectángulo";
        // En versiones futuras se pueden agregar más casos
        default -> throw new IllegalStateException("Forma desconocida: " + shape);
    };
}

These examples illustrate how Java 21 combines traditional robustness with innovations that simplify safe, concurrent development.

6. Java Documentation and Resources

6.1. The Official Java Documentation

Oracle's official documentation and the OpenJDK community are primary sources for a thorough understanding of each language version. It's imperative to consult these resources to stay up-to-date on best practices and new APIs.

6.2. Bleeding Techniques and Code Conventions

Proper indentation and consistent use of naming conventions are essential for code readability and maintainability. It's recommended to follow official style guides (such as Oracle's) and use automatic formatting tools.

6.3. Table of Reserved Words of the Language and Other Elements

In Java, reserved words (or keywords) are lexemes that have a fixed, special meaning for the compiler. This means they cannot be used to name classes, methods, variables, or other identifiers, as they are intended to define the structure and behavior of the language. In addition to these "historical" words, new words have been incorporated in newer versions of Java, some of them as contextual reserved words, which provide improvements in code conciseness and readability (for example, for type inference or handling immutable and sealed classes).

Below is a complete table with the traditional reserved words and some of the new features introduced in later versions (from Java 9 onwards):

Table of Reserved and Contextual Words in Java

Reserved WordBrief descriptionNotes / Version
abstractDeclare abstract classes or methods.Prevents direct instantiation.
assertAllows assertions to be made for debugging.Introduced in Java SE 1.4.
booleanDefines the primitive data type for logical values.
breakInterrupts the execution of a cycle or block switch.
byteDeclares variables of 8-bit integer data type.
caseDefine each option in a statement switch.
catchCatch exceptions thrown in a block try.
charPrimitive type to represent a character.
classDeclare a class.
constReserved but not currently in use.Reserved for future use.
continueInterrupts the current iteration of a loop and moves on to the next.
defaultDefines the default case in a switch or default methods in interfaces.
doStart a cycle do-while.
doublePrimitive type for double-precision decimal numbers.
elseAlternative in a statement if.
enumDeclares an enumerated type.
extendsIndicates that a class inherits from another or an interface extends another.
finalDeclare constants or prevent inheritance/overwriting.
finallyDefines a block that is executed after try/catch, regardless of the outcome.
floatPrimitive type for single-precision decimal numbers.
forStart a cycle for.
gotoReserved but not used in Java.Reserved for future use.
ifStart a condition.
implementsIndicates that a class implements one or more interfaces.
importAllows you to include classes or packages in a source file.
instanceofChecks whether an object is an instance of a given class or interface.
intPrimitive type for 32-bit integers.
interfaceDeclare an interface.
longPrimitive type for 64-bit integers.
nativeIndicates that a method is implemented in native code (e.g., C/C++).
newCreates a new instance of an object.
nullLiteral representing the absence of a value.
packageDeclares the package to which the class belongs.
privateDefines restricted access to the class scope.
protectedDefines access at the package and subclass level.
publicIndicates public access, without restrictions.
returnReturns a value from a method or terminates its execution.
shortPrimitive type for 16-bit integers.
staticDeclare members belonging to the class, not to specific instances.
strictfpRestricts precision and behavior in float calculations.
superRefers to the immediate parent class.
switchStarts a multiple-select statement.
synchronizedMark methods or blocks for secure access in concurrent environments.
thisRefers to the current instance.
throwExplicitly throws an exception.
throwsDeclare the exceptions that a method can propagate.
transientIndicates that an attribute should not be serialized.
tryStart exception handling.
voidSpecifies that a method does not return any value.
volatileMarks a variable as susceptible to asynchronous changes, avoiding local caching.
whileStarts a cycle based on a condition.
varAllows you to declare variables with type inference.Contextual reserved word (since Java 10).
recordDefines an immutable class in a compact way, ideal for storing data.Introduced in Java 16.
sealedRestricts which classes can extend or implement a sealed class or interface.Introduced in Java 17.
permitsExplicitly list the classes that can extend a sealed class.Introduced in Java 17.
non-sealedAllows a subclass of a sealed class to renounce the seal, opening inheritance.Introduced in Java 17.
yieldIt is used in expressions of switch to return a value.Consolidated in Java 14 (previously in preview since Java 13).
moduleBegins the declaration of a module in the Java module system.Introduced in Java 9.
openIndicates that a module allows reflection on certain packages.Introduced in Java 9.
requiresSpecifies the dependency of a module.Introduced in Java 9.
exportsDeclares which packages in a module are available to other modules.Introduced in Java 9.
opensSimilar to exports, but allows runtime reflection.Introduced in Java 9.
usesDeclare the dependency on the implementation of a service.Introduced in Java 9.
providesIndicates that a module offers an implementation of a specific service.Introduced in Java 9.

Additional Considerations

  • Contextual Reserved Words: Some words, like var, are reserved in certain contexts. This means that their special meaning applies only in predefined situations (for example, in the declaration of a variable), but they can be used as identifier names in other contexts where their meaning is not activated.
  • Evolution of Language: With each new version, Java introduces improvements that include new words or reinterpret existing ones. For example, innovations associated with type inference, immutable records, and inheritance control (such as sealed, permits and non-sealed) have expanded the repertoire of words in the language, facilitating more secure and expressive development.
  • Modules and the Module System: Words related to modularization (module, requires, exports, etc.) reflect the paradigm shift introduced in Java 9, which makes it easier to organize and maintain large-scale applications.

This comprehensive and detailed framework not only serves as a quick reference for developers, but also helps them understand how the language's core elements evolve to meet the demands of modern programming.

7. Libraries and Development Tools

7.1. Standard Class Libraries

Java has an extensive set of libraries that cover everything from data management (java.util) to input/output operations (java.io or java.nio), networking, security, and web development. These libraries allow developers to implement complex features without reinventing the wheel.

7.2. Frameworks and Tools (Spring, Hibernate, etc.)

For the development of business applications, frameworks such as Spring either Jakarta EE They offer robust and scalable structures. On the other hand, Hibernate It simplifies object-relational mapping (ORM), facilitating interaction with databases. These tools enhance the language by providing integrated solutions to common industry challenges.

7.3. Dependency Management with Maven and Gradle

The use of automation tools such as Maven and Gradle It's essential for Java project management. It allows you to efficiently define, manage, and resolve library dependencies, as well as automate the compilation, testing, and packaging of applications.

ToolMain UseFile Example
MavenDependency management and project constructionpom.xml
GradleFlexible alternative to Maven with customizable scriptsbuild.gradle

8. Practical Development in Java

8.1. Solving Syntactic and Common Errors

Identifying and correcting syntax errors is an essential part of Java development. Using IDEs (such as IntelliJ IDEA or Eclipse) and compiling with javac They help detect errors at compile time. Static analysis tools (such as SonarQube) are also useful for maintaining clean and robust code.

8.2. My First Java Application: Step-by-Step Example

The traditional “Hello World” is still an excellent starting point for learning basic syntax.

public class HolaMundo {
    public static void main(String[] args) {
        System.out.println("¡Hola, mundo!");
    }
}

Steps to compile and run:

  1. Save the code in a file called HolaMundo.java.
  2. Compile with:
$ javac HolaMundo.java

Run with:

$ java HolaMundo

8.3. Compiling without IDE

It is often valuable to know how to compile from the command line. This is achieved by using the compiler javac and subsequently executing the bytecode with javaThis approach is useful for integration into scripts or server environments.

8.4. Advanced Examples: Concurrency, Streams, and Virtual Threads

Example with Streams:

import java.util.Arrays;

public class Stream {
    public static void main(String[] args) {
        int[] nums = {1, 2, 3, 4, 5};
        Arrays.stream(nums)
            .map(n -> n * n)
            .forEach(System.out::println);
    }
}

Example with Virtual Threads:

public class VirtualThread {
    public static void main(String[] args) throws InterruptedException {
        Thread.startVirtualThread(() -> System.out.println("Ejecutando en un hilo virtual"));
    }
}

These examples demonstrate everything from basic syntax to leveraging new features for concurrent tasks and data processing.

9. Tests and Good Practices

9.1. General Recommendations for Good Programming

  • Readability: Use meaningful names for classes, methods, and variables.
  • Modularity: Separate the logic into well-defined modules or classes.
  • Comments and Documentation: Be sure to document your code and use documentation tools (such as Javadoc).
  • Code Review: Conduct periodic reviews to identify improvements and potential errors.

9.2. Unit Testing, TDD, and Exception Handling

Test-driven development (TDD) and the use of testing frameworks such as JUnit They are recommended practices that guarantee the robustness of the code.

Example of unit test in JUnit 5:

import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;

public class CalculatorTest {
    @Test
    public void testSuma() {
        int resultado = Calculator.sumar(2, 3);
        assertEquals(5, resultado);
    }
}

Likewise, proper exception handling is essential to prevent unexpected application crashes. Use exception blocks. try-catch and logs errors using logging frameworks.

9.3. Debugging, Optimization, and Logging

  • Depuration: Use the debuggers built into IDEs to track and correct errors at runtime.
  • Optimization: Profile the application to identify bottlenecks and use tools like VisualVM for performance analysis.
  • Logging: Implement libraries like Log4j or SLF4J to log events, which will facilitate monitoring and diagnostics in production environments.

10. Summary and Conclusions

Java 21 solidifies the language's trajectory through innovations that maintain its relevance in the modern software development landscape. From the introduction of Virtual Threads to improvements in syntax and data handling with Records and Sealed Classes, Java 21 demonstrates a continued commitment to efficiency, security, and portability. Furthermore, the integration of functional programming practices and robust support for object-oriented design ensure that this language remains a solid choice for projects of any scale.

I don't expect you to know or understand everything, but rather to see the examples, read, and in future chapters we will cover all the topics in this Java SE 21 course.

11. References and Useful Links

  • Official Oracle Java Documentation: https://docs.oracle.com/en/java/
  • OpenJDK: https://openjdk.java.net/
  • Java Code Style Guide (Oracle): https://www.oracle.com/java/technologies/javase/codeconventions-contents.html
  • Communities and Forums (StackOverflow, GitHub): Essential resources to resolve doubts and learn about Java development trends.

Our score
Click to rate this post!
(Votes: 0 Average: 0)
Advertisement
Share on social media...

Deja un comentario

Your email address will not be published. Required fields are marked *

Basic information on data protection
ResponsibleJavier Cachón Garrido +info...
PurposeManage and moderate your comments. +info...
LegitimationConsent of the concerned party. +info...
RecipientsAutomattic Inc., USA to spam filtering. +info...
RightsAccess, rectify and cancel data, as well as some other rights. +info...
Additional informationYou can read additional and detailed information on data protection on our page política de privacidad.

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Scroll al inicio

Descubre más desde javiercachon.com

Suscríbete ahora para seguir leyendo y obtener acceso al archivo completo.

Seguir leyendo