====== 02 - Introducción a Java ====== Java es un lenguaje de programación de alto nivel de propósito general derivado de C. Fue creado por Sun Microsystems Inc. y algunas de sus características son: * Es un lenguaje compilado/interpretado. Aunque en esencia es un lenguaje interpretado, necesita una fase intermedia de compilación como veremos más adelante. * Es un lenguaje totalmente orientado a objetos. * Tiene una gran funcionalidad gracias a sus librerías. * Los programas creados con Java son independientes de la máquina, lo que hace que se puedan ejecutar en una gran variedad de equipos con diferente microprocesadores y sistemas operativos. * Incorpora un recolector de basura (garbase collector) que se encarga de administrar la memoria automáticamente, con lo que no es necesario destruir objetos manualmente. ===== Lenguaje compilado o interpretado ===== Como hemos visto, los lenguajes suelen clasificarse en uno de los dos grupos (compilados o interpretados) en función de si se compila el código fuente antes de su ejecución o no. Java es una mezcla de ambos. Primero compila el código fuente para crear un fichero que almacena lo que se denomina **bytecode** (una especie de pseudocódigo al nivel de código máquina). Para ejecutar este //bytecode// necesitamos un "intérprete", la **Java Virtual Machine** (**JVM**). De esta forma, cualquier equipo que tenga esta //JVM// puede ejecutar los //bytecodes// generados, con lo que se pueden portar entre ordenadores con distintas arquitecturas. ===== JDK y JRE ===== Para instalar esa máquina virtual (//JVM//) y poder ejecutar aplicaciones en Java, podemos optar por dos soluciones: * **Java Runtime Enviroment** (**JRE**): Entorno de ejecución de Java. Contiene la //JVM// y otras herramientas necesarias para ejecutar las aplicaciones Java. //JRE// **no posee el compilador** ni las herramientas para desarrollar las aplicaciones Java, con lo que **solo se puede ejecutar el código, pero no desarrollarlo**. * **Java Development Kit** (**JDK**): Además de la //JVM//, contiene herramientas para el desarrollo de aplicaciones Java. Entre otras, tiene la herramienta **javac**, que se encarga de compilar el código escrito en Java. El //JDK// ya contiene el //JRE//. {{ :clase:daw:prog:1eval:jdk_jre.png?400 |}} Por lo tanto, para desarrollar aplicaciones Java **necesitamos tener instalado en nuestra máquina //JDK//**. ===== Versiones JDK ===== Existen varias implentaciones de JDK, cada una con características y enfoques distintos, entre las cuales destacan: **[[https://www.oracle.com/java/technologies/downloads/|JDK]]** * Desarrollado y mantenido por Oracle. * Es de uso gratuito solo para desarrollo y pruebas, pero requiere una licencia de pago para entornos de producción en versiones posteriores a Java 8. * Incluye herramientas como javac, java, y jlink. * Oracle lanza versiones LTS (Long-Term Support) con actualizaciones de seguridad y soporte extendido. **[[https://openjdk.org/|OpenJDK]]** * Implementación de código abierto del JDK, liderada por Oracle pero con contribuciones de otras empresas y la comunidad. * Totalmente gratuito y con actualizaciones regulares. * Es la base de otras distribuciones del JDK. **[[https://adoptium.net/es/|Temurin JDK (Adoptium)]]** * Administrado por la Fundación Eclipse a través del proyecto Adoptium. * Es una de las implementaciones más populares de OpenJDK. * Proporciona builds gratuitos, probados y certificados. **[[https://aws.amazon.com/es/corretto/?filtered-posts.sort-by=item.additionalFields.createdDate&filtered-posts.sort-order=desc|Amazon Corretto]]** * Distribución de OpenJDK mantenida por Amazon. * Diseñada para entornos de producción con mejoras de rendimiento y estabilidad. * Soporte gratuito con actualizaciones de seguridad a largo plazo. **[[https://www.azul.com/downloads/?package=jdk#zulu|Azul Zulu JDK]]** * Distribución de OpenJDK mantenida por Azul Systems. * Ofrece versiones gratuitas y de pago con soporte comercial. * Disponible para diversas plataformas, incluyendo versiones específicas para IoT y tiempo real. **[[https://bell-sw.com/libericajdk/|Liberica JDK]]** * Desarrollado por BellSoft. * Compatible con todas las versiones de OpenJDK y con soporte extendido para versiones antiguas. * Incluye JavaFX en su distribución completa. Cada una de estas versiones tiene ventajas dependiendo del entorno en el que se use. Para proyectos empresariales, Temurin, Corretto y Azul Zulu son opciones populares por su estabilidad y soporte extendido. Para desarrolladores individuales, OpenJDK suele ser suficiente. Una de las ventajas de Temurin JDK y OpenJDK es que cuentan con contenedores Docker oficiales, lo que facilita su implementación en entornos de desarrollo y producción. Gracias a esto, los desarrolladores pueden ejecutar aplicaciones Java en entornos aislados y reproducibles, optimizando la portabilidad y la gestión de dependencias. Además, estas imágenes oficiales suelen recibir actualizaciones de seguridad y mejoras de rendimiento, garantizando estabilidad y compatibilidad con diferentes sistemas operativos y arquitecturas. ===== Instalación de JDK ===== En nuestro caso, vamos a instalar Temurin JDK. En su [[https://adoptium.net/es/installation/|página]] están las instrucciones de instalación según el método y SO elegido. Para verificar la correcta instalación de la //JVM// y el compilador: java -version openjdk version "21.0.6" 2025-01-21 LTS OpenJDK Runtime Environment Temurin-21.0.6+7 (build 21.0.6+7-LTS) OpenJDK 64-Bit Server VM Temurin-21.0.6+7 (build 21.0.6+7-LTS, mixed mode, sharing) javac -version javac 21.0.6 Si queremos desarrollar aplicaciones Java, tenemos que asegurarnos que tenemos instalado, además de la //JVM//, el compilador de Java con la opción **javac**. Por último, debemos añadir java al PATH del sistema. En Ubuntu, por ejemplo, tenemos varias formas de hacerlo. Primero añadimos la variable JAVA_HOME. Para eso, editamos el archivo /etc/environment: sudo nano /etc/environment Añadir la siguiente línea al final del archivo: JAVA_HOME="/usr/lib/jvm/java-21.0.6+7" Recargamos el archivo sin necesidad de reiniciar la sesión: source /etc/environment Y comprobamos que nuestra variable apunta donde toca: echo $JAVA_HOME /usr/lib/jvm/java-21.0.6+7 Ahora, podemos añadir java al PATH del sistema añadiendo la siguiente línea al archivo /etc/profile: export PATH="$JAVA_HOME/bin:$PATH" La carpeta de instalación de Java no tiene porqué ser la misma en tu ordenador. ===== Compilación y ejecución de aplicaciones Java ===== Para empezar a programar una aplicación Java solo necesitamos tener instalado el //JDK// y algún editor de texto plano (más adelante veremos como usar un IDE para ayudarnos en la creación de programas). Por ejemplo, crea un nuevo archivo y escribe lo siguiente en él (no te preocupes ahora por el contenido, ya iremos viendo poco a poco qué es cada cosa): class HolaMundo { public static void main(String[] args) { System.out.println("Hola mundo"); } } Guárdalo con el nombre //HolaMundo.java//. Abre un terminal y ejecuta la siguiente orden: java HolaMundo.java Si todo ha ido bien, la salida debería ser: Hola mundo Igual te has dado cuenta que hemos utilizado la orden //java// en lugar de //javac//. En realidad, si usamos la orden //java// sobre un archivo con extensión //.java//, lo que hace es compilarlo y ejecutarlo. Entonces, ¿qué diferencia hay entre usar //java// y //javac//? Mira en la carpeta donde está el archivo //HolaMundo.java//. Debería contener solo el archivo que hemos creado. Ejecuta ahora la siguiente orden: javac HolaMundo.java Parece que no hay respuesta en la terminal. Vuelve a mirar la carpeta. Ahora tenemos un archivo nuevo llamado //HolaMundo.class//. Lo que hemos hecho es compilar el archivo //.java// y crear un nuevo archivo //.class// con el código ya compilado. A partir de ahora, puedes ejecutar el archivo HolaMundo.class en cualquier máquina que tenga instalada la //JVM//. Si ejecuta ahora la orden: java HolaMundo Deberías ver la misma salida por pantalla que antes (//Hola mundo//). Fíjate que para ejecutar archivos ya compilados (//.class//) no necesitamos añadirle la extensión, simplemente escribimos el nombre del archivo (HolaMundo) sin //.class//. Además, ahora la ejecución tarda menos, ya que no hace falta volver a compilar la aplicación. ==== Archivos .class ==== Ya hemos visto que escribimos nuestro código fuente (lenguaje Java) en los archivos //.java// y después los compilamos creando los archivos //.class//. Entonces, ¿se crea un archivo //.class// por cada archivo //.java// que tengamos en nuestra aplicación? No exactamente. Vuelve a crear un archivo llamado HolaMundo2.java y añade el siguiente contenido: class HolaMundo2 { public static void main(String[] args) { System.out.println("Hola mundo 2"); } } class HolaMundo3 { public static void main(String[] args) { System.out.println("Hola mundo 3"); } } Compila el archivo con la opción //javac//. Ahora nos ha creado 2 archivos nuevos: //HolaMundo2.class// y //HolaMundo3.class//. Lo que hace el compilador es crear un archivo por cada clase definida en nuestra aplicación, da igual que estén en el mismo archivo u otro diferente. Aunque por ahora no vamos a entrar en POO (Programación Orientada a Objetos) hay que tener en cuenta una cosa: las clases en Java suelen llevar visibilidad (//public//, //protected// o //private//). Los archivos //.java// solo pueden contener una clase //public//. Por ahora, nosotros no vamos a preocuparnos de eso. Podemos crear las clases como //public// o, directamente, sin visibilidad. ===== Estructura de una aplicación java ===== Vamos a ver la estructura del ejemplo anterior //HolaMundo.java//: class HolaMundo { public static void main(String[] args) { System.out.println("Hola mundo"); } } Lo primero que aparece es //class HolaMundo//. Como hemos dicho, Java es un lenguaje totalmente orientado a objetos, con lo que todo tiene que estar dentro de una clase. Para definir una clase en Java se utiliza la palabra reservada **class**. A continuación, se escribe el nombre de la clase que elije el programador. En realidad, más adelante veremos como también se suele añadir la visibilidad de la clase de esta forma: public class HolaMundo Pero por ahora no vamos a preocuparnos de éso. Definiremos nuestras clases sin la visibilidad. Lo normal es que separemos nuestras clases en archivos diferentes, aunque nada nos impide crear dos clases en el mismo archivo (con la restricción de que solo una de ellas puede ser pública). Después de la definición de la clase, hay una llave de apertura (**{**). En Java, los bloques de código (clases, funciones...) se delimitan con las llaves: { bloque código Java... } ==== El método main() ==== Lo siguiente es la definición del método //main()//. Un método o función es un bloque de código que podemos invocar en cualquier parte (veremos como restringir su ámbito más adelante) llamándolo por su nombre. El método //main()// es el método de entrada de una aplicación Java. Cuando ejecutemos la aplicación, el primer método que se ejecutará será //main()//. Este método tiene que tener el nombre correctamente escrito (en minúsculas), ser público, llevar delante la palabra reservada //static// y recibir como parámetros //String[] args// (en realidad, el nombre del parámetro puede cambiar, pero por simplificar, lo vamos a escribir siempre de la misma forma). Iremos viendo a lo largo del curso que significa cada una de estas cosas. Lo importante por ahora es saber que todo el código que metamos dentro de nuestro método //main()// se ejecutará automáticamente cuando ejecutemos nuestra aplicación. Como hemos visto antes, todo el bloque de código dentro del método está encerrado entre llaves ({ }). En nuestro ejemplo, cuando ejecutamos la aplicación se ejecuta la orden //System.out.println("Hola Mundo")//, que muestra por pantalla la cadena de texto "Hola Mundo". ==== Secuencia de instrucciones ==== Para escribir las instrucciones de nuestro programa, debemos hacerlo de forma secuencial, es decir, una a continuación de la otra y separadas por punto y coma (**;**). Lo normal es escribir cada instrucción en una línea nueva: public static void main(String[] args) { System.out.println("Hola mundo"); System.out.println("Hola universo"); } Aunque podemos escribir las instrucciones en la misma línea, ya que al final escribimos el separador de instrucciones (//;//): public static void main(String[] args) { System.out.println("Hola mundo");System.out.println("Hola universo"); } En cualquier caso, no es recomendable usar esta forma, ya que complica la legibilidad del código. ==== Identación del código ==== Al contrario que //Python//, en Java no estamos obligados a identar (sangrar) nuestro código. Podemos escribir nuestras aplicaciones de tal forma que todas las instrucciones empiecen en la misma línea: class HolaMundo { public static void main(String[] args) { System.out.println("Hola mundo"); System.out.println("Hola universo"); } } Igual que antes, no se recomienda escribir código de esta manera. Compara el código anterior con el siguiente: class HolaMundo { public static void main(String[] args) { System.out.println("Hola mundo"); System.out.println("Hola universo"); } } En el segundo caso, vemos enseguida que la clase //HolaMundo// tiene un método //main()// y podemos mirar su código sin problemas, mientras que en el primer caso, nos costaría saber cuántos métodos tiene implementada la clase que estamos mirando. Piensa que estos ejemplos son sencillos con muy pocas líneas de código, pero a medida que aumenten éstas, agradeceremos seguir una guía de estilo al escribir código. ==== Comentarios ==== En Java podemos escribir comentarios de varias formas: * Comentarios de línea: Se escriben precedidos de dos barras (//) * Comentarios de bloque (varias líneas): Se encierra el comentario entre /* y */. /** Esto es un comentario de bloque. Puede ocupar varias líneas */ class HolaMundo { public static void main(String[] args) { //Esta instrucción escribe Hola mundo por pantalla System.out.println("Hola mundo"); } } El compilador ignorará todo lo que hay escrito dentro de los comentarios, con lo que podemos usarlos para aclarar trozos de código. No se debe abusar de los comentarios. Como dice Robert C. Martin en su libro //Código limpio//, es mejor que el código se explique por sí mismo que añadir comentarios. A lo largo del curso veremos estrategias para minimizar al máximo los comentarios. Una estrategia bastante habitual cuando estamos programando aplicaciones es comentar partes de código mientras vamos probando cosas. Ésto no es malo de por sí, pero tenemos que asegurarnos de dejar el código lo más limpio posible (sin código comentado) cuando terminemos esas pruebas, ya que si no corremos el riesgo de dejar en la aplicación final trozos enteros de código comentado, con lo que podemos confundir a nuevos programadores que se incorporen al proyecto. ===== Ejercicios ===== **Ejercicio 1** Comprueba si en tu ordenador está instalado OpenJDK 17. Si no lo está, instálalo (asegúrate de configurar correctamente la variable de entorno con el path de Java). Comprueba la versión instalada de Java (también del compilador). **Ejercicio 2** Crea el archivo //Ejercicio2.java// y añádele el siguiente contenido: class Ejercicio2 { public static void main(String[] args) { System.out.println("Soy el ejercicio 2 del tema de introducción de Java"); } } Ejecuta el archivo directamente con la orden //java// en el terminal. Comprueba que sale la frase por pantalla y que no te ha creado el archivo //.class//. **Ejercicio 3** Compila el archivo anterior (//Ejercicio2.java//). Comprueba que te ha creado el archivo //Ejercicio2.class// y ejecútalo para mostrar la frase por pantalla. **Ejercicio 4** Crea el siguiente archivo //Ejercicio4.java//: class Ejercicio4 { public void main(String[] args) { System.out.println("Hola mundo"); } } Compílalo y comprueba que no da ningún error. Ejecuta el archivo compilado. ¿Qué error te da? Arréglalo, vuelve a compilarlo y ejecútalo esta vez sin errores. **Ejercicio 5** Crea el archivo //Ejercicio2.java// con el siguiente contenido: class Ejercicio2 { public Static Main(String args) { /Mostramos por pantalla la frase Hola mundo System.out.println("Hola mundo") /* TODO: Mostrar por pantalla otra frase } Compila el archivo y arregla los posibles errores que vayan saliendo.