Java – Paso a paso Tema 4

Written by lopezatienza on 09/08/2009 – 00:39 -

TEMA4. El lenguaje Java

En esta Unidad Didáctica se pretende dar una introducción al lenguaje Java, explicando que es, sus características, como funciona y como configurar e instalar el compilador, además de otros aspectos de interés.

1. ¿Qué es Java?
2. El lenguaje Java
3. La arquitectura de la máquina Java
4. El modelo de carga
5. El formato de ficheros de clases
6. El entorno de aplicaciones
7. La especificación e implementación
8. ¿Dónde se utiliza Java?
9. ¿Podemos hacerlo todo con Java?
10. El entorno de desarrollo

1. ¿Qué es Java?

Cuando oímos hablar de Java lo primero que pensamos es en un lenguaje de programación, si bien es cierto que dicha afirmación no se ajusta del todo a la realidad.

Cuando nos preguntan acerca de qué es Java, podríamos responder que se trata de un lenguaje, una arquitectura de máquina, un modelo de carga, un formato de ficheros, un entorno de aplicaciones, una especificación y una implementación.

Existen muchas versiones acerca de los orígenes de Java, pero la más extendida es la que lo muestra como lenguaje de pequeños electrodomésticos.

Hace algunos años, Sun Microsystems decidió introducirse en el mercado de la electrónica de consumo y desarrollar programas para pequeños dispositivos electrónicos. James Gosling, el miembro del equipo con más experiencia en lenguajes de programación, decidió que las ventajas de eficiencia que aportaba C o C++ no compensaban el coste que suponían los desarrollos. Además, dichos lenguajes deben ser compilados para un chip concreto, de modo que si éste cambia ha de compilarse de nuevo, lo cual era un inconveniente para un mercado tan cambiante.

James Gosling había estado desarrollando en su tiempo libre un lenguaje con una sintaxis similar a la de C++ y en el que intentaba remediar las deficiencias que observaba en este último. Este lenguaje fue bautizado con el nombre de Oak y decidieron mejorar sus características para, posteriormente, utilizarlo.

Este proyecto no tuvo el éxito esperado y quedó relegado al olvido durante algún tiempo. Más adelante Bill Joy, cofundador de Sun, vio en Oak el instrumento adecuado a través de Internet para disputar a Microsoft su primicia absoluta en el terreno del software. Tras un cambio de nombre y modificaciones de diseño, Java fue presentado en agosto de 1995.

En respuesta a la pregunta planteada al principio, podemos afirmar que Java es un verdadero lenguaje orientado a objetos. Incorpora algunos de los conceptos más modernos y potentes sobre el diseño de lenguajes de programación. Se diseñó procurando ocultar las complejidades que en muchos otros lenguajes es visible, procurando obtener, de esta forma, un mayor rendimiento de los programadores. A pesar de que Java aplica estrictamente muchas reglas en tiempo de compilación, también posee características que le permiten escribir código muy dinámico.

Java es un lenguaje compilado pero, al contrario que con la mayoría de los otros lenguajes compilados, su código no es específico de la máquina ni del sistema operativo. Cualquier sistema con una máquina virtual de Java (JVM, Java Virtual Machine) puede ejecutar el mismo Java compilado.

Entre las capacidades y características que incluye el lenguaje, tenemos la gestión de excepciones, la recolección de basura, una colección de clases muy completa para el desarrollo de aplicaciones de bases de datos, de gráficos o de comunicaciones, y muchas otras más que han originado la gran aceptación de la industria informática por él.

Los programas Java pueden ser de muchos tipos, pero el más conocido es el de los applets. Un applet es código Java que se descarga automáticamente de la web y que se ejecuta dentro del explorador web, en el ordenador del usuario. Este tipo de programas no requiere instalación, posibilita interfaces de usuario muy ricas y lleva asociado unos estrictos mecanismos de seguridad.

Pero Java también puede usarse para desarrollar aplicaciones completas. Estas aplicaciones se instalan en los sistemas concretos y no tienen las restricciones de los applets. Con ellas se puede realizar prácticamente cualquier tarea que pueda hacerse con otros lenguajes de programación, desde simples aplicaciones locales hasta complejas aplicaciones distribuidas.

Por otro lado, es preciso mencionar que Java tiene un fértil campo en las aplicaciones con tecnología de servidor. De hecho, actualmente es posible desarrollar aplicaciones web, componentes distribuidos y servicios web.

2. El lenguaje Java

Inicialmente se planteó como una alternativa al lenguaje C++ y uno de sus objetivos era mejorar los déficits de éste último. Entre los remedios que plantea Java podemos citar:

- Robustecimiento de la programación orientada a objetos y eliminación de todas las características no orientadas a objetos.
- Eliminación de la posibilidad de manipular directamente punteros a memoria.
- Eliminación de la confusa gestión de memoria por parte de los diseñadores de aplicaciones.
- Reforzamiento de la seguridad de los tipos.
- Realización de comprobaciones en tiempo de ejecución para problemas comunes como moldeos ilegales y referencias a objetos nulos.
- Soporte para programación multihilo directamente en el lenguaje.
- Mejora en la gestión de excepciones (manejo de errores)

Como lenguaje de programación, podemos citar de él las siguientes características:

- Simple. Ofrece la funcionalidad de un lenguaje potente pero sin las características menos usadas y más confusas de éstos. El ejemplo más claro puede ser el recolector de basura, que evita que andemos preocupándonos de liberar memoria. Otro ejemplo, la supresión de punteros.
- Orientado a objetos. Soporta encapsulación, herencia y polimorfismo.
- Distribuido. Proporciona las librerías y herramientas necesarias para que las aplicaciones puedan ser distribuidas. Se ha desarrollado con extensas capacidades de interconexión a red y soporta varios protocolos de red.
- Robusto. Realiza varias comprobaciones tanto en tiempo de compilación y en tiempo de ejecución. Entre ellos mencionar la comprobación de tipos y de límites de arrays.
- Portable. Esto no se refiere a la independencia de la plataforma, si no a la portabilidad en cuanto a desarrollo. Por ejemplo, los enteros son siempre enteros de 32 bits, con independencia de la plataforma.
- Multiplataforma. No es necesario recompilar las aplicaciones Java para los distintos sistemas en que van a ser explotadas.
- Multihilo. Permite múltiplos hilos de ejecución, es decir, muchas actividades simultáneas dentro del mismo programa. Las ventajas de esto son un mejor rendimiento interactivo (el usuario no percibe tanto la ocupación de la máquina) y un mejor comportamiento en tiempo real (aunque sea algo muy limitado por el sistema operativo).
- Dinámico. Cuando una aplicación se lanza, no se cargan todas las librerías que requiere, sino que la carga es bajo demanda. Las librerías nuevas o actualizadas no paralizarán las aplicaciones en funcionamiento.

Java está diseñado para facilitar la labor del programador, disminuyendo los tiempos de aprendizaje y de programación gracias a su sencillez y a su capacidad de detectar errores; sin embargo, Java también tiene sus defectos: Java deja hacer desbordamiento sin dar error ni en tiempo de compilación ni en tiempo de ejecución.

3. La arquitectura de la máquina Java

La especificación Java no sólo describe un lenguaje de alto nivel, también define la máquina a bajo nivel y el conjunto de instrucciones que es capaz de ejecutar.

La implantación de la arquitectura se ha dejado a la libre elección de los proveedores. Esta arquitectura bien podría ser un microprocesador Java (hace unos años se desarrollaron algunos), o bien, una máquina virtual (software). Actualmente, existen máquinas virtuales para la mayoría de los entornos existentes (Windows, MacOs, Linux, los diversos UNIX).

Además de describir el motor de ejecución, la especificación describe otros comportamientos como el arranque, la carga y el apagado.

4. El modelo de carga

El modelo de carga Java lo hace un lenguaje único. La carga de las clases tiene lugar dinámicamente durante la ejecución del programa. Con esto se rompe la dinámica tradicional de la compilación, enlazado, carga y ejecución que todos conocemos y que es requerida para crear y ejecutar programas.

La carga de clases tiene lugar en varios pasos:

- Lectura de los bloques.
- Verificación de que los bloques definen una clase bien estructurada que contiene código Java bien estructurado.
- Construcción de una estructura de clase global.
- Resolución de las referencias.
- Control de acceso, permitiendo que una aplicación o entorno decida las reglas de acceso para la carga de la clase.

La carga de clases se produce bajo demanda según se necesite. Este concepto no es nuevo y, de hecho, lo vemos rutinariamente en las librerias dinámicas, los modelos de objeto (CORBA, COM y otros) y la capacidad plug-in de algunos productos. Pero lo que sí es nuevo es la total integración de la carga de clases con el lenguaje y el entorno.

Permitir la carga de clases desde fuentes dispares (disco local, web, dispositivos de red y otros) es un gran adelanto en la programación orientada a objetos, ya que permite tratar los objetos del código ejecutable con la misma facilidad que antes estaba reservada solo para los objetos de datos.

5. El formato de ficheros de clases

Java también define, para el código, un paquete independiente de la plataforma. Este paquete recibe el nombre de archivo de clases. Estos archivos son generados por un compilador Java por lo que pasan a estar disponibles para ser ejecutados. Los archivos de clase se encontrarán, normalmente, en sistemas de ficheros o empaquetados en archivos (ficheros “zip” o “jar”) y el sistema de carga de clases de Java esperará encontrarlos con la extensión “.class”.

6. El entorno de aplicaciones

Teniendo en cuenta que las aplicaciones actuales se ejecutan en un entorno proporcionado por librerías y subsistemas, Java proporciona a las aplicaciones todo el entorno, desde los servicios básicos de entrada / salida hasta los interfaces de usuario para trabajo en red. Así pues, Java ha ido aportando entornos cada vez más mejorados a través de sus distintas versiones del JDK (Java Development Kit).

Actualmente, dispone de un entorno de aplicaciones con componentes GUI (Graphic User Interface), soporte de impresión, métodos de invocación remota,
conectividad de bases de datos, gráficos 2D, una API de audio...

7. La especificación e implementación

Java es sobre todo una especificación y a partir de ésta es posible crear cualquier parte de él. Podríamos crear nuestro propio compilador. Es por ello que diversas corporaciones hayan creado implementaciones, tanto gratuitas como comerciales.

8. ¿Dónde se utiliza Java?

Como indicamos al principio de este tema, Java es una plataforma tan virtuosa que ha encontrado múltiples escenarios en los que asentarse. A continuación vamos una ver una relación de algunos de ellos:

- Aplicaciones Java independientes bajo diversos sistemas operativos: Linux,Windows, MacOS, diversas modalidades de UNIX, etc.
- Entornos de ejecución de applets proporcionados por los navegadores más populares.
- Servidores web para la generación dinámica de contenidos.
- JavaOS. Sistema operativo de Sun para ordenadores y sistemas de redes.
- En sistemas de gestión de bases de datos como Oracle para soporte de procedimientos almacenados.
- Cajas de televisión que ejecutan JavaTV
- Tarjetas inteligentes. Son tarjetas de plástico con un chip y una máquina virtual de Java completa.
- Controladores integrados en dispositivos como impresoras y cámaras.
- En joyería. Anillos y relojes, por ejemplo con una máquina virtual integrada y que se emplean para identificación, comercio electrónico y criptografía.

9. ¿Podemos hacerlo todo con Java?

Java es un sueño por muchas y variadas razones. Incorpora las tecnologías más interesantes desarrolladas a lo largo de la historia de la informática como por ejemplo: recolección de basura, código independiente de la plataforma y carga dinámica de clases.

Pero este es justamente el problema, es lento. Con el desarrollo de mejoras en las especificaciones Java se irá paliando esto, pero hay buenas razones para pensar que nunca podrá competir en velocidad con las aplicaciones nativas compiladas.

Alguno de los problemas que no se pueden manejar actualmente con Java son:

- Problemas críticos de prestaciones. Para ello se requieren aplicaciones nativas o componentes nativos en las aplicaciones Java.
- Los problemas que implican gran catidad de memoria o requisitos de entrada/salida.
- Problemas específicos de la plataforma. Java logra la independencia de la plataforma y para ello no aprovecha las características de los lenguajes nativos. Para intentar solventar este problema existe la librería JNI (Java Native Interface), que permite mezclar Java y código nativo.
- GUI. Java tiene una GUI pero su rendimiento es inferior al nativo del propio sistema. Actualmente Java tiene más éxito en entornos no GUI (como
servidores).

Como conclusión:

- Java es, sobre todo, una especificación de un lenguaje, una arquitectura de máquina, un modelo de carga, un formato de ficheros, un entorno de aplicaciones, una especificación y una implementación.
- El lenguaje Java se caracteriza por ser: simple, orientado a objetos, distribuido, robusto, portable, multiplataforma, multihilo y dinámico.

10. El entorno de desarrollo

Existen muchos entornos que permiten desarrollar código para Java, tanto comerciales como gratuitos. La compañía creadora de Java, Sun Microsystems, distribuye gratuitamente el Java Development Kit (JDK). Éste es un conjunto de programas y librerías que permiten desarrollar, compilar y ejecutar programas en Java.

Asimismo, tenemos también una reducida versión del JDK que sólo permite ejecutar código Java y que recibe el nombre de Java Runtime Environment (JRE)

Existen también los llamados entornos de desarrollo integrados que permiten realizar todas las tareas (escritura, compilación y ejecución) de forma centralizada y sin tener que ir cambiando de aplicación. Ayudan en las tareas de desarrollo mediante mecanismos como plantillas de clases, ayudas en línea y depuración asistida, entre otros.

El compilador de Java

Es una de las herramientas que se incluyen en el JDK. Se encarga de analizar los ficheros fuente y generar los correspondientes ficheros compilados (ficheros de bytecodes). En caso de encontrar errores nos mostrará las líneas que los provocan junto con el mensaje de error. Los ficheros fuentes de java tienen la extensión “.java” y los ficheros compilados tienen la extensión “.class”.

Invocaremos el compilador con el comando “javac” seguido del nombre del programa o programas a compilar. De igual forma, podemos hacer uso de numerosas opciones, las cuales pueden varias de unas versiones a otras del JDK.

El intérprete de Java

Como ya hemos mencionado, Java se diseño para que el código fuera portable entre plataformas sin necesidad de volver a compilarlo. Para ello se previó la existencia de un intérprete, más comúnmente llamado Máquina Virtual de Java (JVM).

El compilador de Java genera un código que no está relacionado con ninguna plataforma y que, posteriormente, la JVM interpretará convirtiéndolo al código específico de la plataforma en la que se ejecuta.

El intérprete se invoca con el comando “java” seguido del nombre del programa ejecutar. También permite usar varias opciones y nuevamente nos remitiremos a la documentación para saber los detalles de cada una de ellas.

Accesibilidad al entorno

Para poder compilar y ejecutar las aplicaciones Java es necesario tener acceso al directorio en el que se encuentran el compilador y el intérprete.
Para poder compilar y ejecutar cómodamente deberíamos añadir el directorio “\bin” del JDK a la variable de entorno PATH.

Para los usuarios de DOS y Windows, desde el símbolo del sistema tendremos que escribir:

set PATH=%PATH%;c:\java\bin

Para los usuarios de UNIX y Linux: desde la ventana de terminal tendremos que escribir:

export PATH=$PATH:/home/usuariojava/java/bin

La variable de entorno PATH no es específica de Java, si no que más bien es un mecanismo de los sistemas operativos para localizar programas que no se encuentran en el directorio actual. Pero ahora vamos con otra variable de entorno que sí lo es, estamos hablando de CLASSPATH.

Ya hemos hablado de que Java carga dinámicamente las clases según las necesita, pero ¿dónde busca estas clases? Este es el papel de la variable de entorno CLASSPATH, indicar a Java donde buscar las clases y librerías propias (el API de Java) y las clases de usuario. Esta variable puede incluir tantos elementos de los siguientes tipos como sea necesario:

- Nombre de directorio que contenga ficheros con extensión “class”.
- Nombre de fichero con extensión “zip” que contenga ficheros con extensión “class”. Recordemos que un fichero zip es un fichero comprimido.
- Nombre de fichero con extensión “jar” que contenga ficheros con extensión “class”. Los ficheros jar son ficheros comprimidos con la herramienta jar que incorpora el JDK de Java.

Generalmente asignamos a la variable CLASSPATH como primer valor el “.”

Representa el directorio en curso. Así, busca en primer lugar el directorio actual porque resulta muy común trabajar con clases que residen en una misma ubicación y están relacionadas, por lo que el cargador de clases debe saber encontrarlas.

EJEMPLO: HELLO WORLD!

Veamos el código:

1          //Fichero HelloWorld.java
2          class HelloWorld{
3          public static void main(String[] args){
4          System.out.println(“Hello World!”);
5          }
6          }

Vamos a explicar cada línea del código:

Línea 1: es un simple comentario de tipo línea en el que hemos colocado el nombre del fichero. El compilador ignorará todo lo que va desde los caracteres “//” hasta el final de la línea. Tan mala es la falta de comentarios como el abuso de ellos.

Pensemos que los comentarios son de mucha utilidad, tanto para otras personas que tengan que revisar nuestro código, como para nosotros mismos en futuras revisiones.

Línea 2: declara el nombre de la clase. Usamos la palabra reservada class seguida del nombre que queremos darle a nuestra clase, en este caso es “HelloWorld”.Ya sabemos que Java es un lenguaje orientado a objetos, por tanto, nuestro programa ha de ser definido como una clase. Por convención, las clases Java se definen con la primera letra en mayúsculas.

Línea 3: Estamos ante una declaración de un método de la clase que estamos definiendo. Este método se llama main, se define como público (public), estático (static) y no va a devolver nada (void) cuando se ejecute. Se define como público para que pueda ser conocido fuera de la clase y como estático para disponer de él sin tener que crear un objeto. Después del nombre, y encerrada entre paréntesis, vemos la definición de los parámetros que puede recibir el método. En nuestro ejemplo se trata de un parámetro “args” y de tipo array de cadenas de texto. Este método será el punto de partida inicial de nuestro programa cuando lo ejecutemos.

Línea 4: puede resultar extraña para aquellos que no conozcan la sintaxis de la programación orientada a objetos. Se trata de una llamada al método println del flujo de salida (out) estándar del sistema (System). Dicho método se encarga de mostrar por pantalla la línea que se le indique.

Las líneas restantes son el cierre de la definición del método main (línea 5) y el cierre de la definición de la clase HelloWorld (línea 6).
Ahora abrimos el editor que más nos guste, escribimos el código anterior, y lo guardamos con el nombre “HelloWorld.java”. Es muy importante tener en cuenta que Java distingue entre mayúsculas y minúsculas. Si nos equivocamos obtendremos un error que puede resultar algo frustante para un principiante.

Ahora vamos a compilar nuestra clase. Para ello usaremos la herramienta “javac” indicándole el nombre de nuestra clase.

javac HelloWorld.java

Si lo hemos hecho todo bien no obtendremos ningún mensaje al terminar la compilación y habremos obtenido un fichero llamado “HelloWorld.class”.

Lo siguiente es la ejecución. Veremos, por tanto, el resultado de nuestro trabajo. Ahora invocaremos al intérprete, llamado “java”, indicándole que queremos ejecutar.

java HelloWorld

Y obtendremos como respuesta al texto “Hello World”. Si no definimos la variable de entorno CLASSPATH, tendríamos que haber usado la sintaxis siguiente:

java –classpath . HelloWorld

Hemos visto que el intérprete necesita el nombre de una clase. El nombre del fichero que contiene la clase no es significativo pero por convención se usa el mismo nombre que el de la clase que contiene. Esto es así porque un fichero puede contener más de una clase, aunque también por convención no se suele hacer.

Para aclarar todo esto vamos a ver otro ejemplo. Vamos a escribir dos clases:

“Clase 1” y “Clase 2”. La primera la guardaremos como “Fichero1.java” y la segunda como “Fichero2.java”.

class Clase1{
public static void main(String[] args){
System.out.println(“Soy Clase1”);
}
}

class Clase2{
public static void main(String[] args){
System.out.println(“Soy Clase2”);
}
}

Ahora las compilamos usando la siguiente sintaxis para ahorrarnos trabajo:

javac Fichero*.java

Tras esto tendremos los ficheros “Fichero1.class” y “Fichero2.class”. Vamos a hacer varias pruebas y explicaremos los resultados:

- En primer lugar intentamos ejecutar “Clase1” indicándole el nombre del fichero que la contiene. Para ello escribimos “java Fichero1”. Veremos que
el mensaje de error que obtenemos indica que no existe la clase “Fichero1”.

Así es, no tenemos definida ninguna clase con ese nombre.

- ¿Y si probamos indicándole que nos ejecute “Fichero1.class”. De esa forma debería ejecutarse “Clase1” ya que está contenida en él. Pues bien, si
probamos a escribir “java Fichero1.class” veremos que obtenemos de nuevo un error en el que se nos indica que no encuentra la clase. Esta vez el
mensaje se refiere a una clase llamada “class” de un paquete llamado “Fichero1”.

- Ya sólo nos falta indicársela por su nombre, ahora escribimos “java Clase1”.

En esta ocasión observamos que sí funciona. Si probamos con “java Clase2” vemos que también la encuentra. Ahora podemos entender la utilidad de
indicar el directorio actual en la variable de entorno CLASSPATH, ya que el intérprete ha encontrado las clases porque estaban accesibles a través de ella.

Las conclusiones son las siguientes:

1) Para compilar es necesario decirle al compilador el nombre del fichero de clases.
2) Para ejecutar hay que indicarle al intérprete cual es la clase que queremos ejecutar y éste la buscará en los directorios y ficheros especificados en la variable de entorno CLASSPATH.

Para cerrar este apartado, hemos de hacer una aclaración importante. Este último ejemplo ha tratado de una clase llamada “Clase1” contenida en un fichero llamado “Fichero1.java”. Se ha realizado así por ser conveniente para lo que se explicaba, pero convencionalmente no se recomienda este uso. Las recomendaciones indican que el fichero debe poseer el mismo nombre que la clase que contiene.

CONVENCIONES Y NOMENCLATURA EN LA PROGRAMACIÓN JAVA

Con respecto a los nombres de variables, las reglas del lenguaje Java son muy amplias y permiten mucha libertad, pero es habitual seguir ciertas normas que faciliten la lectura y el mantenimiento de los programas. Ya hemos dicho que los nombres en Java son sensibles a mayúsculas y minúsculas. Por ejemplo, podemos tener en un programa las variables “altura”, “Altura” y “ALTURA” y serían tres variables distintas.

Por convención, se recomienda seguir las siguientes reglas:

- Normalmente se emplean nombres con minúsculas salvo las excepciones que se enumeran en los siguientes puntos.
- En los nombres que se componen de varias palabras es aconsejable colocar una detrás de otra poniendo en mayúscula la primera letra de cada palabra.
- Los nombres de las clases y las interfaces empiezan siempre por mayúscula.
- Los nombres de objetos, métodos y variables empiezan siempre por minúscula.
- Los nombres de las variables finales (las constantes) se definen siempre con mayúsculas.

Ejemplo práctico:

class Circunferencia { //Es una clase
private final double PI=3.14159; //Es una variable final
private double elRadio; //Es una variable miembro de la clase

public void establecerRadio(double radio){ //Son método y variable local
elRadio=radio;
}
public double calcularLongitud( ) { //Es un método
return (2*PI*elRadio);
}
}

<< Volver al tema anterior  || >> Ir al tema siguiente

 

Referencias:

 

http://www.jmordax.com/

 


Autor: Antonio Lopez Atienza


Tags:
Posted in Java | No Comments »

Leave a Comment

 

RSS
MCC D5E