====== 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//**. ==== Instalación de JDK ==== Podemos instalar //JDK// desde la [[https://www.oracle.com/java/technologies/downloads/|página oficial de Java]]. Buscamos la versión SE (Standard Edition) que queramos instalar, y seguimos las instrucciones. También tenemos otra alternativa, que es instalar **OpenJDK**. La diferencia fundamental entre ambas es la licencia y el soporte que recibe cada una: * **Prestaciones**: Realmente no hay una diferencia significativa entre ambas plataformas, ya que la construcción de //Oracle JDK// esta basada en //OpenJDK//. * **Licencia**: En el caso de //Oracle JDK// las empresas o particulares no podrán tener acceso a las actualizaciones de la plataforma después de Enero de 2019 a menos que compres una licencia con Oracle. En el caso de //OpenJDK// el uso es libre. * **Soporte**: En el caso de los bugs que se encuentran en //Oracle JDK// son corregidos inmediatamente y distribuidos a sus clientes de pago. En el caso de //OpenJDK// debemos esperar un poco a tener las correcciones ya que esta basada en las aportaciones de la comunidad Open Source. **//OpenJDK// es una implementación oficial de Java SE**. Este proyecto es administrado por //JDK Project// y, al igual que la //JDK de Oracle//, los nuevos releases de //OpenJDK// son cada 6 meses. La gran mayoría de las empresas optan por utilizar //JDK// en lugar de //OpenJDK// debido a que los clientes de pago de Java requieren actualizaciones y fixes. Sin embargo, si estamos aprendiendo a programar con Java o realizando proyectos propios, //OpenJDK// puede ser una excelente opción. En nuestro caso, vamos a instalar //OpenJDK//. La instalación es igual de sencilla que //JDK//: ir a su [[http://jdk.java.net/|página oficial]], descargar la versión que queramos y seguir las instrucciones de instalación. Como ejemplo, la instalación de la versión 17 en Ubuntu sería: sudo apt-get install openjdk-17-jdk Para verificar la correcta instalación de la //JVM// y el compilador: java --version openjdk 17.0.3 2022-04-19 OpenJDK Runtime Environment (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1) OpenJDK 64-Bit Server VM (build 17.0.3+7-Ubuntu-0ubuntu0.20.04.1, mixed mode, sharing) javac --version javac 17.0.3 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 una variable de entorno con el path de la instalación de Java: sudo gedit /etc/environment Añadir la siguiente línea al final del archivo: JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64" 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.