martes, 8 de noviembre de 2011

HISTORIA DE JAVA
Los lenguajes de programación C y Fortran se han utilizado para diseñar algunos de los sistemas más complejos en lenguajes de programación estructurada, creciendo hasta formar complicados procedimientos. De ahí provienen términos como "código de espagueti" o "canguros" referentes a programas con múltiples saltos y un control de flujo difícilmente trazable.
No sólo se necesitaba un lenguaje de programación para tratar esta complejidad, sino un nuevo estilo de programación. Este cambio de paradigma de la programación estructurada a la programación orientada a objetos, comenzó hace 30 años con un lenguaje llamado Simula67.
El lenguaje C++ fue un intento de tomar estos principios y emplearlos dentro de las restricciones de C. Todos los compiladores de C++ eran capaces de compilar programas de C sin clases, es decir, un lenguaje capaz de interpretar dos estilos diferentes de programación. Esta compatibilidad ("hacia atrás") que habitualmente se vende como una característica de C++ es precisamente su punto más débil. No es necesario utilizar un diseño orientado a objetos para programar en C++, razón por la que muchas veces las aplicaciones en este lenguaje no son realmente orientadas al objeto, perdiendo así los beneficios que este paradigma aporta.
Así Java utiliza convenciones casi idénticas para declaración de variables, paso de parámetros, y demás, pero sólo considera las partes de C++ que no estaban ya en C.
Las principales características que Java no hereda de C++ son:
  • Punteros: Las direcciones de memoria son la característica más poderosa de C++. El inadecuado uso de los punteros provoca la mayoría de los errores de colisión de memoria, errores muy difíciles de detectar. Además, casi todos los virus que se han escrito aprovechan la capacidad de un programa para acceder a la memoria volátil (RAM) utilizando punteros. En Java, no existen punteros, evitando el acceso directo a la memoria volátil.
  • Variables globales: Con ellas cualquier función puede producir efectos laterales, e incluso se pueden producir fallos catastróficos cuando algún otro método cambia el estado de la variable global necesaria para la realización de otros procesos. En Java lo único global es el nombre de las clases.
  • goto: Manera rápida de arreglar un programa sin estructurar el código. Java no tiene ninguna sentencia goto. Sin embargo Java tiene las sentencias break y continue que cubren los casos importantes de goto.
  • Asignación de memoria: La función malloc de C, asigna un número especificado de bytes de memoria devolviendo la dirección de ese bloque. La función free devuelve un bloque asignado al sistema para que lo utilice. Si se olvida de llamar a free para liberar un bloque de memoria, se están limitando los recursos del sistema, ralentizando progresivamente los programas. Si por el contrario se hace un free sobre un puntero ya liberado, puede ocurrir cualquier cosa. Más tarde C++ añadió new y delete, que se usan de forma similar, siendo todavía el programador, el responsable de liberar el espacio de memoria. Java no tiene funciones malloc ni free. Se utiliza el operador new para asignar un espacio de memoria a un objeto en el montículo de memoria. Con new no se obtiene una dirección de memoria sino un descriptor al objeto del montículo. La memoria real asignada a ese objeto se puede mover a la vez que el programa se ejecuta, pero sin tener que preocuparse de ello. Cuando no tenga ninguna referencia de ningún objeto, la memoria ocupada estará disponible para que la reutilice el resto del sistema sin tener que llamar a free o delete. A esto se le llama recogida de basura. El recolector de basura se ejecuta siempre que el sistema esté libre, o cuando una asignación solicitada no encuentre asignación suficiente.
  • Conversión de tipos insegura: Los moldeados de tipo (type casting) son un mecanismo poderoso de C y C++ que permite cambiar el tipo de un puntero. Esto requiere extremada precaución puesto que no hay nada previsto para detectar si la conversión es correcta en tiempo de ejecución. En Java se puede hacer una comprobación en tiempo de ejecución de la compatibilidad de tipos y emitir una excepción cuando falla.
Comienzos
Java fue diseñado en 1990 por James Gosling, de Sun Microsystems, como software para dispositivos electrónicos de consumo. Curiosamente, todo este lenguaje fue diseñado antes de que diese comienzo la era World Wide Web, puesto que fue diseñado para dispositivos electrónicos como calculadoras, microondas y la televisión interactiva.
En los primeros años de la década de los noventa, Sun Microsystems decidió intentar introducirse en el mercado de la electrónica de consumo y desarrollar programas para pequeños dispositivos electrónicos. Tras unos comienzos dudosos, Sun decidió crear una filial, denominada FirstPerson Inc., para dar margen de maniobra al equipo responsable del proyecto.
Inicialmente Java se llamó Oak (roble en inglés), aunque tuvo que cambiar de denominación, debido a que dicho nombre ya estaba registrado por otra empresa. Se dice este nombre se le puso debido a la existencia de tal árbol en los alrededores del lugar de trabajo de los promotores del lenguaje.
Tres de las principales razones que llevaron a crear Java son:
  1. Creciente necesidad de interfaces mucho más cómodas e intuitivas que los sistemas de ventanas que proliferaban hasta el momento.
  2. Fiabilidad del código y facilidad de desarrollo. Gosling observó que muchas de las características que ofrecían C o C++ aumentaban de forma alarmante el gran coste de pruebas y depuración. Por ello en los sus ratos libres creó un lenguaje de programación donde intentaba solucionar los fallos que encontraba en C++.
  3. Enorme diversidad de controladores electrónicos. Los dispositivos electrónicos se controlan mediante la utilización de microprocesadores de bajo precio y reducidas prestaciones, que varían cada poco tiempo y que utilizan diversos conjuntos de instrucciones. Java permite escribir un código común para todos los dispositivos.
Por todo ello, en lugar de tratar únicamente de optimizar las técnicas de desarrollo y dar por sentada la utilización de C o C++, el equipo de Gosling se planteó que tal vez los lenguajes existentes eran demasiado complicados como para conseguir reducir de forma apreciable la complejidad de desarrollo asociada a ese campo. Por este motivo, su primera propuesta fue idear un nuevo lenguaje de programación lo más sencillo posible, con el objeto de que se pudiese adaptar con facilidad a cualquier entorno de ejecución.
Basándose en el conocimiento y estudio de gran cantidad de lenguajes, este grupo decidió recoger las características esenciales que debía tener un lenguaje de programación moderno y potente, pero eliminando todas aquellas funciones que no eran absolutamente imprescindibles.
Para más información véase [Cuenca, 1997].
Primeros proyectos en que se aplicó Java
El proyecto Green fue el primero en el que se aplicó Java, y consistía en un sistema de control completo de los aparatos electrónicos y el entorno de un hogar. Con este fin se construyó un ordenador experimental denominado *7 (Star Seven). El sistema presentaba una interfaz basada en la representación de la casa de forma animada y el control se llevaba a cabo mediante una pantalla sensible al tacto. En el sistema aparecía ya Duke, la actual mascota de Java.
Más tarde Java se aplicó a otro proyecto denominado VOD (Video On Demand) en el que se empleaba como interfaz para la televisión interactiva que se pensaba iba a ser el principal campo de aplicación de Java. Ninguno de estos proyectos se convirtió nunca en un sistema comercial, pero fueron desarrollados enteramente en un Java primitivo.
Una vez que en Sun se dieron cuenta de que a corto plazo la televisión interactiva no iba a ser un gran éxito, instaron a FirstPerson a desarrollar nuevas estrategias que produjeran beneficios. Entre ellas se encontraba la aplicación de Java a Internet, la cual no se consideró productiva en ese momento.
Para más información véase [Froufe, 1997].
Resurgimiento de Java
Aunque muchas de las fuentes consultadas señalan que Java no llegó a caer en un olvido, lo cierto es que tuvo que ser Bill Joy (cofundador de Sun y uno de los desarrolladores principales del sistema operativo Unix de Berckley) el que sacó a Java del letargo en que estaba sumido. Joy juzgó que Internet podría llegar a ser el campo adecuado para disputar a Microsoft su primacía en el terreno del software, y vio en Oak el instrumento idóneo para llevar a cabo estos planes.
Para poder presentarlo en sociedad se tuvo que modificar el nombre de este lenguaje de programación y se tuvo que realizar una serie de modificaciones de diseño para poderlo adaptar al propósito mencionado. Así Java fue presentado en sociedad en agosto de 1995.
Algunas de las razones que llevaron a Bill Joy a pensar que Java podría llegar a ser rentable son:
  • Java es un lenguaje orientado a objetos: Esto es lo que facilita abordar la resolución de cualquier tipo de problema.
  • Es un lenguaje sencillo, aunque sin duda potente.
  • La ejecución del código Java es segura y fiable: Los programas no acceden directamente a la memoria del ordenador, siendo imposible que un programa escrito en Java pueda acceder a los recursos del ordenador sin que esta operación le sea permitida de forma explícita. De este modo, los datos del usuario quedan a salvo de la existencia de virus escritos en Java. La ejecución segura y controlada del código Java es una característica única, que no puede encontrarse en ninguna otra tecnología.
  • Es totalmente multiplataforma: Es un lenguaje sencillo, por lo que el entorno necesario para su ejecución es de pequeño tamaño y puede adaptarse incluso al interior de un navegador.
Las consecuencias de la utilización de Java junto a la expansión universal de Internet todavía están comenzando a vislumbrarse.
Existen muchas críticas a Java debido a su lenta velocidad de ejecución, aproximadamente unos 20 veces más lentos que un programa en lenguaje C. Sun está trabajando intensamente en crear versiones de Java con una velocidad mayor.
El problema fundamental de Java es que utiliza una representación intermedia denominada código de byte para solventar los problemas de portabilidad. Los códigos de byte posteriormente se tendrán que transformar en código máquina en cada máquina en que son utilizados, lo que ralentiza considerablemente el proceso de ejecución.
La solución que se deriva de esto parece bastante obvia: fabricar ordenadores capaces de comprender directamente los códigos de byte. Éstas serían unas máquinas que utilizaran Java como sistema operativo y que no requerirían en principio de disco duro porque obtendrían sus recursos de la red.
A los ordenadores que utilizan Java como sistema operativo se les llama Network Computer, WebPC o WebTop. La primera gran empresa que ha apostado por este tipo de máquinas ha sido Oracle, que en enero de 1996 presentó en Japón su primer NC (Network Computer), basado en un procesador RISC con 8 Megabytes de RAM. Tras Oracle, han sido compañías del tamaño de Sun, Apple e IBM las que han anunciado desarrollos similares.
La principal empresa en el mundo del software, Microsoft, que en los comienzos de Java no estaba a favor de su utilización, ha licenciado Java, lo ha incluido en Internet Explorer (versión 3.0 y posteriores), y ha lanzado un entorno de desarrollo para Java, que se denomina Visual J++.
El único problema aparente es la seguridad para que Java se pueda utilizar para transacciones críticas. Sun va a apostar por firmas digitales, que serán clave en el desarrollo no sólo de Java, sino de Internet.
Especulación sobre el futuro de Java
En opinión de los redactores de este tutorial, Java es una plataforma que le falta madurar, pero que a buen seguro lo va a hacer. La apuesta realizada por empresas con mucho peso específico ha sido tan grande que va a dar un impulso a Java que no le permitirá caer
Además, el parque de productos (entornos de desarrollo, bibliotecas, elementos de conectividad...) ya disponible en la actualidad es tan amplio que es improbable que se quede en nada.
Por otra parte, la relación simbiótica que tiene con Internet (y por derivación con las Intranets) es un punto a favor de Java de muy difícil refutación.
CARACTERÍSTICAS DE JAVA
Introducción
No es arriesgado afirmar que Java supone un significativo avance en el mundo de los entornos software, y esto viene avalado por tres elementos claves que diferencian a este lenguaje desde un punto de vista tecnológico:
  • Es un lenguaje de programación que ofrece la potencia del diseño orientado a objetos con una sintaxis fácilmente accesible y un entorno robusto y agradable.
  • Proporciona un conjunto de clases potente y flexible.
  • Pone al alcance de cualquiera la utilización de aplicaciones que se pueden incluir directamente en páginas Web (aplicaciones denominadas applets).
Java aporta a la Web una interactividad que se había buscado durante mucho tiempo entre usuario y aplicación.
A lo largo de este apartado se estudian en detalle las principales características de Java.
Potente
a.) Orientación a objetos
En este aspecto Java fue diseñado partiendo de cero, no siendo derivado de otro lenguaje anterior y no tiene compatibilidad con ninguno de ellos.
En Java el concepto de objeto resulta sencillo y fácil de ampliar. Además se conservan elementos "no objetos", como números, caracteres y otros tipos de datos simples.
b.) Riqueza semántica
Pese a su simpleza se ha conseguido un considerable potencial, y aunque cada tarea se puede realizar de un número reducido de formas, se ha conseguido un gran potencial de expresión e innovación desde el punto de vista del programador.
c.) Robusto
Java verifica su código al mismo tiempo que lo escribe, y una vez más antes de ejecutarse, de manera que se consigue un alto margen de codificación sin errores. Se realiza un descubrimiento de la mayor parte de los errores durante el tiempo de compilación, ya que Java es estricto en cuanto a tipos y declaraciones, y así lo que es rigidez y falta de flexibilidad se convierte en eficacia. Respecto a la gestión de memoria, Java libera al programador del compromiso de tener que controlar especialmente la asignación que de ésta hace a sus necesidades específicas. Este lenguaje posee una gestión avanzada de memoria llamada gestión de basura, y un manejo de excepciones orientado a objetos integrados. Estos elementos realizarán muchas tareas antes tediosas a la vez que obligadas para el programador.
d.) Modelo de objeto rico
Existen varias clases que contienen las abstracciones básicas para facilitar a los programas una gran capacidad de representación. Para ello se contará con un conjunto de clases comunes que pueden crecer para admitir todas las necesidades del programador.
Además la biblioteca de clases de Java proporciona un conjunto único de protocolos de Internet.
El conjunto de clases más complicado de Java son sus paquetes gráficos AWT (Abstract Window Toolkit) y Swing. Estos paquetes implementan componentes de una interfaz de usuario gráfica básica común a todos los ordenadores personales modernos.
Simple
a.) Fácil aprendizaje
El único requerimiento para aprender Java es tener una comprensión de los conceptos básicos de la programación orientada a objetos. Así se ha creado un lenguaje simple (aunque eficaz y expresivo) pudiendo mostrarse cualquier planteamiento por parte del programador sin que las interioridades del sistema subyacente sean desveladas.
Java es más complejo que un lenguaje simple, pero más sencillo que cualquier otro entorno de programación. El único obstáculo que se puede presentar es conseguir comprender la programación orientada a objetos, aspecto que, al ser independiente del lenguaje, se presenta como insalvable.
b.) Completado con utilidades
El paquete de utilidades de Java viene con un conjunto completo de estructuras de datos complejas y sus métodos asociados, que serán de inestimable ayuda para implementar applets y otras aplicaciones más complejas. Se dispone también de estructuras de datos habituales, como pilas y tablas hash, como clases ya implementadas.
Existirá una interfaz Observer/Observable que permitirá la implementación simple de objetos dinámicos cuyo estado se visualiza en pantalla.
El JDK (Java Development Kit) suministrado por Sun Microsystems incluye un compilador, un intérprete de aplicaciones, un depurador en línea de comandos, y un visualizador de applets entre otros elementos.
Interactivo y orientado a red
a.) Interactivo y animado
Uno de los requisitos de Java desde sus inicios fue la posibilidad de crear programas en red interactivos, por lo que es capaz de hacer varias cosas a la vez sin perder rastro de lo que debería suceder y cuándo. Para se da soporte a la utilización de múltiples hilos de programación (multithread).
Las aplicaciones de Java permiten situar figuras animadas en las páginas Web, y éstas pueden concebirse con logotipos animados o con texto que se desplace por la pantalla. También pueden tratarse gráficos generados por algún proceso. Estas animaciones pueden ser interactivas, permitiendo al usuario un control sobre su apariencia.
b.) Arquitectura neutral
Java está diseñado para que un programa escrito en este lenguaje sea ejecutado correctamente independientemente de la plataforma en la que se esté actuando (Macintosh, PC, UNIX…). Para conseguir esto utiliza una compilación en una representación intermedia que recibe el nombre de códigos de byte, que pueden interpretarse en cualquier sistema operativo con un intérprete de Java. La desventaja de un sistema de este tipo es el rendimiento; sin embargo, el hecho de que Java fuese diseñado para funcionar razonablemente bien en microprocesadores de escasa potencia, unido a la sencillez de traducción a código máquina hacen que Java supere esa desventaja sin problemas.
c.) Trabajo en red
Java anima las páginas Web y hace posible la incorporación de aplicaciones interactivas y especializadas. Aporta la posibilidad de distribuir contenidos ejecutables, de manera que los suministradores de información de la Web pueden crear una página de hipertexto (página Web) con una interacción continuada y compleja en tiempo real; el contenido ejecutable es transferido literalmente al ordenador del usuario.
Los protocolos básicos para trabajar en Internet están encapsulados en unas cuantas clases simples. Se incluyen implementaciones ampliables de los protocolos FTP, HTTP, NNTP y SMTP junto con conectores de red de bajo nivel e interfaces de nombrado. Esto le permite interactuar con esos servicios de red poderosos sin tener que comprender realmente los detalles de bajo nivel de esos protocolos. Este lenguaje está diseñado para cumplir los requisitos de entrega de contenidos interactivos mediante el uso de applets insertados en sus páginas HTML. Además, las clases de Java admiten muy bien estos protocolos y formatos. El envío de las clases de Java a través de Internet se realiza con gran facilidad, ya que existe una interfaz unificada, resolviendo así los típicos problemas de diferencia de versiones.
Java proporciona un conjunto de clases para tratar con una abstracción de los conectores de red (sockets) originales de la versión UNIX de Berckley, encapsular la noción de una dirección de Internet o conectar sockets con flujos de datos de Entrada/Salida.
Con todas estas posibilidades aumenta el dinamismo y competitividad de la Web, puesto que es capaz de captar el interés del usuario durante largo tiempo y permite a los programadores convertir la Web en un sistema de entrega de software.
d.) Applets
Una applet (miniaplicación) es un pequeño programa en Java transferido dinámicamente a través de Internet. Presentan un comportamiento inteligente, pudiendo reaccionar a la entrada de un usuario y cambiar de forma dinámica. Sin embargo, la verdadera novedad es el gran potencial que Java proporciona en este aspecto, haciendo posible que los programadores ejerzan un control sobre los programas ejecutables de Java que no es posible encontrar en otros lenguajes.
Mucho más
a.) Seguridad
Existe una preocupación lógica en Internet por el tema de la seguridad: virus, caballos de Troya, y programas similares navegan de forma usual por la red, constituyendo una amenaza palpable. Java ha sido diseñado poniendo un énfasis especial en el tema de la seguridad, y se ha conseguido lograr cierta inmunidad en el aspecto de que un programa realizado en Java no puede realizar llamadas a funciones globales ni acceder a recursos arbitrarios del sistema, por lo que el control sobre los programas ejecutables no es equiparable a otros lenguajes.
Los niveles de seguridad que presenta son:
  • Fuertes restricciones al acceso a memoria, como son la eliminación de punteros aritméticos y de operadores ilegales de transmisión.
  • Rutina de verificación de los códigos de byte que asegura que no se viole ninguna construcción del lenguaje.
  • Verificación del nombre de clase y de restricciones de acceso durante la carga.
  • Sistema de seguridad de la interfaz que refuerza las medidas de seguridad en muchos niveles.
En futuras versiones se prevé contar también con encriptación y técnicas similares.
b.) Lenguaje basado en C++
Java fue desarrollado basándose en C++, pero eliminando rasgos del mismo poco empleados, optándose por una codificación comprensible. Básicamente, encontramos las siguientes diferencias con C++:
  • Java no soporta los tipos struct, union ni punteros.
  • No soporta typedef ni #define.
  • Se distingue por su forma de manejar ciertos operadores y no permite una sobrecarga de operadores.
  • No soporta herencia múltiple.
  • Java maneja argumentos en la línea de comandos de forma diversa a como lo hacen C o C++.
  • Tiene una clase String que es parte del paquete java.lang y se diferencia de la matriz de caracteres terminada con un nulo que usan C y C++.
  • Java cuenta con un sistema automático para asignar y liberar memoria, con lo que no es necesario utilizar las funciones previstas con este fin en C y C++.
c.) Gestión de la Entrada/Salida
En lugar de utilizar primitivas como las de C para trabajar con ficheros, se utlizan primitivas similares a las de C++, mucho más elegantes, que permiten tratar los ficheros, sockets, teclado y monitor como flujos de datos.
De este modo se pueden utilizar dichas primitivas para cualquier operación de Entrada/Salida.
d.) Diferentes tipos de aplicaciones
En Java podemos crear los siguientes tipos de aplicaciones:
  • Aplicaciones: Se ejecutan sin necesidad de un navegador.
  • Applets: Se pueden descargar de Internet y se observan en un navegador.
  • JavaBeans: Componentes software Java, que se puedan incorporar gráficamente a otros componentes.
  • JavaScript: Conjunto del lenguaje Java que puede codificarse directamente sobre cualquier documento HTML
  • Servlets: Módulos que permiten sustituir o utilizar el lenguaje Java en lugar de programas CGI (Common Gateway Interface) a la hora de dotar de interactividad a las páginas Web.
COMPARATIVA CON OTROS LENGUAJES DE PROGRAMACIÓN ORIENTADOS A OBJETO
Introducción
En este apartado se va a comparar Java con otros lenguajes de programación orientados a objeto.
En principio Java fue diseñado tomando C y C++ como base para la creación de un nuevo lenguaje con la modificación de todos aquellos aspectos que no eran útiles o dificultosos para la programación de componentes electrónicos de bajo coste. Para ello el nuevo lenguaje debía incluir interfaces cómodas, debía ser fiable y fácil de desarrollar y los programas debían ser portables de un sistema a otro sin ningún tipo de problema.
Comparación de los tipos de datos
a.) Tipos de datos simples (primitivos)
Java es muy parecido a C++ en el juego básico de tipos de datos con algunas pequeñas modificaciones.
En Java se distingue entre tipos de datos primitivos y clases, aunque existen unas clases especiales (envoltorios o wrappers) que permiten modificar los tipos de datos primitivos.
Los tipos de datos primitivos (o simples) pueden ser numéricos, booleanos o caracteres.
b.) Datos numéricos
Hay cuatro tipos numéricos: byte de 1 byte, short de 2 bytes, int de 4 bytes, y los long de 8 bytes. El tipo más habitual de los cuatro es el tipo int. El byte viene a sustituir el tipo char de C++, ya que Java introduce una interpretación diferente al tipo de datos char.
Las principales diferencias con C++ son:
  • No existe un tipo sin signo (unsigned) para los números en Java.
  • Los tipos numéricos reales son el float (8 bytes) y el double (16 bytes).
  • Los números que utilizan coma flotante (por ejemplo 18.96) son considerados double por defecto, y habrá que realiza un moldeado (casting) explícito para que sean float.
c.) Caracteres
Los datos carácter en Java se basan en los de C++ que a su vez son heredados de C. Los caracteres son Unicode de 2 bytes. Los caracteres Unicode son valores de 2 bytes sin signo, con lo que se define obtiene un rango de 65535 caracteres diferentes, que son suficientes para las los diferentes lenguajes y sistemas de representación del planeta.
El carácter de datos del lenguaje Java proviene del tradicional C. Hay que señalar que los caracteres en C++ eran de sólo 1 byte, con lo que en Java podremos representar muchos más caracteres que en C++.
d.) Datos booleanos
En Java se definen para las variables con valores Verdadero/Falso o Sí/No, en definitiva, valores bi-estado. Una variable booleana puede tener los valores true (verdadero) o false (falso). Son parecidos a los de C++, aunque en cualquier caso, y a diferencia de C++ estas variables no pueden ser convertidas a datos numéricos, y es un tipo de datos básico.
Operadores relacionales y aritméticos.
Se permite en Java los mismos operadores que C++, con la variación de >>> (desplazamiento sin signo) y la utilización del operador + para la concatenación de cadenas de caracteres.
Vectores
Los vectores en Java, a diferencia de C++, son una clase de objetos. Un vector es un objeto real con una representación en tiempo real. Se pueden declarar y almacenar vectores de cualquier tipo, y almacenar también vectores de vectores para obtener matrices (vectores con varias dimensiones). En este último aspecto no existe diferencia con C++.
Cadenas
Las cadenas en Java son objetos del lenguaje, no existen seudo-arrays de caracteres (cadenas) como era el caso de C++. Existen dos tipos de cadenas de objetos:
Las que se obtienen de la clase String, para cadenas de sólo lectura.
Las que se obtienen de la clase StringBuffer para cadenas que se pueden modificar.
Al igual que C++, el compilador de Java entiende que una cadena de caracteres rodeada de dobles comillas es una cadena, y es iniciada como un objeto de tipo String (en C++ sería como vector de caracteres con el carácter fin de cadena ‘\0’ al final de la misma).
Otras características
a.) Introducción
En este apartado se va a comparar Java con los lenguajes C++ y Smalltalk (primer lenguaje que presentaba un modelo de objeto).
Característica
Java
Smalltalk
C++ 
Sencillez
No
Robustez
No
Seguridad
Algo
No
Interpretado
No
Dinamicidad
No
Portabilidad
Algo
No
Neutralidad
Algo
No
Threads
No
No
Garbage Colection
No
Excepciones
Algunas
Representación
Alta
Media
Alta
Tabla 1: Comparación entre Java, SmallTalk y C++
b.) Sencillez
Java tiene una sencillez que no posee C++ aunque sí Smalltalk. Esto es debido a que una de las razones de la creación de Java es la de obtener un lenguaje parecido a C++ pero reduciendo los errores más comunes de la programación, algo que se logra con mucho éxito puesto que Java reduce un 50% los errores que se comenten en C++ entre los que destacan:
  • Eliminación de la aritmética de punteros y de las referencias.
  • Desaparecen los registros (struct), heredados del paradigma estructurado.
  • No se permite ni la definición de tipos (typedef) ni la de macros (#define).
  • Ya no es necesario liberar memoria (free o delete).
De todas formas, lo que Java hace, en realidad, es la eliminación de palabras reservadas, y la utilización de un intérprete bastante pequeño.
c.) Robustez
Java realiza verificaciones en busca de problemas tanto en tiempo de compilación como en tiempo de ejecución, lo que hace que se detecten errores lo antes posible, normalmente en el ciclo de desarrollo. Algunas de estas verificaciones que hacen que Java sea un lenguaje robusto son:
  • Verificación del código de byte.
  • Gestión de excepciones y errores.
  • Comprobación de punteros y de límites de vectores.
Se aprecia una clara diferencia con C++ quién no realiza ninguna de estas verificaciones.
d.) Seguridad
En Java no se permite los accesos ilegales a memoria, algo que sí se permitía en C++. Esto es algo muy importante puesto que este tipo de problema puede ocasionar la propagación de virus y otras clases de programas dañinos por la red.
El código Java pasa muchos tests antes de ejecutarse en una máquina. El código se pasa a través de un verificador de código de byte que comprueba el formato de los fragmentos de código y aplica un probador de teoremas para detectar fragmentos de código ilegal, código que falsea punteros, viola derechos de acceso sobre objetos o intenta cambiar el tipo o clase de un objeto.
Algunos de los conocimientos que podemos obtener de los códigos de byte si pasan la verificación sin generar ningún mensaje de error son:
  • El código no produce desbordamiento de operandos en la pila.
  • El tipo de los parámetros de todos los códigos de operación es conocido y correcto.
  • No ha ocurrido ninguna conversión ilegal de datos, tal como convertir enteros en punteros.
  • El acceso a los campos de un objeto se sabe si es legal mediante las palabras reservadas public, private y protected.
  • No hay ningún intento de violar las reglas de acceso y seguridad establecidas.
Por todo esto, y por no permitirlo mediante Java la utilización de métodos de un programa sin los privilegios del núcleo (kernel) del sistema operativo, la obligación de autentificación por clave pública para la realización de modificaciones, se considera Java un lenguaje seguro. Todo esto no lo incorporan ni C++ ni Smalltalk, por lo que Java es el único de los tres considerable como seguro.
e.) Lenguaje interpretado
Java es un lenguaje que puede ejecutar el código directamente, es decir es un "lenguaje interpretado". Esto es una característica que sí que posee Smalltalk, aunque no C++. No obstante, y aunque en teoría se consumen menos recursos siendo los lenguajes interpretados, el actual compilador que existe es bastante lento, unas 20 veces menos rápido que C++. Esto normalmente no es vital para la aplicación ni demasiado apreciable por el usuario, y además esta diferencia se está reduciendo con los nuevos compiladores JIT (Just In Time).
f.) Dinamicidad
Para la obtención de un mayor provecho de la tecnología orientada a objetos, Java no intenta conectar todos los módulos que comprenden una aplicación hasta el tiempo de ejecución. Esta característica ya es contemplada por Smalltalk, aunque no C++, que enlaza todos los módulos cuando se compila.
g.) Portabilidad
Un programa Java puede ser ejecutado en diferentes entornos, algo imposible para C++.
h.) Neutralidad
Se dice que Java tiene una arquitectura neutra puesto que compila su código a un fichero objeto de formato independiente de la arquitectura de la máquina en que se ejecutará.
Cualquier máquina que tenga el sistema de ejecución (JRE o Java Runtime Enviroment) puede ejecutar ese código objeto, sin importar en modo alguno la máquina en que ha sido generado.
Actualmente existen sistemas de ejecución (JRE) para Solaris 2.x, SunOs 4.1.x, Windows 95, Windows NT, Linux, Irix, Aix, Mac, Apple y probablemente haya grupos de desarrollo trabajando el portado a otras plataformas.
No es así para C++ y para Smalltalk, donde el código generado podrá ejecutarse únicamente en la plataforma en la que se generó.
i.) Threads
Java permite múltiples hilos (multithreading) antes de su ejecución y en tiempo de ejecución. La posibilidad de construir pequeños procesos o piezas independientes de un gran proceso permite programar de una forma más sencilla y es una herramienta muy potente que no se ofrece en C++.
j.) Recolección automática de basura ( Garbage colection )
Java modifica completamente la gestión de la memoria que se hace en C/C++. En C/C++ se utilizan punteros, reservas de memoria (con las ordenes malloc, new, free, delete...) y otra serie de elementos que dan lugar a graves errores en tiempo de ejecución difícilmente depurables.
Java tiene operadores nuevos para reservar memoria para los objetos, pero no existe ninguna función explícita para liberarla.
La recolección de basura (objetos ya inservibles) es una parte integral de Java durante la ejecución de sus programas. Una vez que se ha almacenado un objeto en el tiempo de ejecución, el sistema hace un seguimiento del estado del objeto, y en el momento en que se detecta que no se va a volver a utilizar ese objeto, el sistema vacía ese espacio de memoria para un uso futuro.
Esta gestión de la memoria dinámica hace que la programación en Java sea más fácil.
k.) Representación
Uno de los objetivos perseguidos en el desarrollo de Java era la obtención de programas con interfaces cómodas e intuitivas. Esto también se permite en C++, aunque con unos métodos más costosos, y en ningún caso con interfaces portables como los que Java crea.
Tanto en Java como en C++ se logran unas interfaces con una representación mejor que la que se puede alcanzar con Smalltalk.
FUNDAMENTOS
Introducción
Java es un lenguaje orientado a objetos, que se deriva en alto grado de C++, de tal forma que puede ser considerado como un C++ nuevo y modernizado o bien como un C++ al que se le han amputado elementos heredados del lenguaje estructurado C.
Tokens
Un token es el elemento más pequeño de un programa que es significativo para el compilador. Estos tokens definen la estructura de Java.
Cuando se compila un programa Java, el compilador analiza el texto, reconoce y elimina los espacios en blanco y comentarios y extrae tokens individuales. Los tokens resultantes se compilan, traduciéndolos a código de byte Java, que es independiente del sistema e interpretable dentro de un entorno Java.
Los códigos de byte se ajustan al sistema de máquina virtual Java, que abstrae las diferencias entre procesadores a un procesador virtual único.
Los tokens Java pueden subdividirse en cinco categorías: Identificadores, palabras clave, constantes, operadores y separadores.
a.) Identificadores
Los identificadores son tokens que representan nombres asignables a variables, métodos y clases para identificarlos de forma única ante el compilador y darles nombres con sentido para el programador.
Todos los identificadores de Java diferencian entre mayúsculas y minúsculas (Java es Case Sensitive o Sensible a mayúsculas) y deben comenzar con una letra, un subrayado(_) o símbolo de dólar($). Los caracteres posteriores del identificador pueden incluir las cifras del 0 al 9. Como nombres de identificadores no se pueden usar palabras claves de Java.
Además de las restricciones mencionadas existen propuestas de estilo. Es una práctica estándar de Java denominar:
  • Las clases: Clase o MiClase.
  • Las interfaces: Interfaz o MiInterfaz.
  • Los métodos: metodo() o metodoLargo().
  • Las variables: altura o alturaMedia.
  • Las constantes: CONSTATE o CONSTANTE_LARGA.
  • Los paquetes: java.paquete.subpaquete.
Sin entrar en más detalle en la siguiente línea de código se puede apreciar la declaración de una variable entera (int) con su correspondiente identificador:
int alturaMedia;
b.) Palabras clave
Las palabras claves son aquellos identificadores reservados por Java para un objetivo determinado y se usan sólo de la forma limitada y específica. Java tiene un conjunto de palabras clave más rico que C o que C++, por lo que sí está aprendiendo Java con conocimientos de C o C++, asegúrese de que presta atención a las palabras clave de Java.
Las siguientes palabras son palabras reservadas de Java:
abstact
boolean
break
byte
byvalue
case
cast
catch
char
class
const
continue
default
do
double
else
extends
false
final
finally
float
for
future
generic
goto
if
implements
import
inner
instanceof
int
interface
long
native
new
null
operator
outer
package
private
protected
public
rest
return
short
static
super
switch
syncroniced
this
throw
throws
transient
true
try
var
void
volatile
while

Tabla 2: Palabras reservadas Java
Las palabras subrayadas son palabras reservadas pero no se utilizan. La definición de estas palabras clave no se ha revelado, ni se tiene un calendario respecto a cuándo estará alguna de ellas en la especificación o en alguna de las implementaciones de Java.
c.) Literales y constantes
Los literales son sintaxis para asignar valores a las variables. Cada variables es de un tipo de datos concreto, y dichos tipos de datos tienen sus propios literales.
Mediante determinados modificadores (static y final) podremos crear variables constantes, que no modifican su valor durante la ejecución de un programa. Las constantes pueden ser numéricas, booleanas, caracteres (Unicode) o cadenas (String).
Las cadenas, que contienen múltiples caracteres, aún se consideran constantes, aunque están implementadas en Java como objetos.
Veamos un ejemplo de constante declarada por el usuario:
final static int ALTURA_MAXIMA = 200;
Se puede observar que utilizamos final static, para que la variable sea total y absolutamente invariable.
d.) Operadores
Conocidos también como operandos, indican una evaluación o computación para ser realizada en objetos o datos, y en definitiva sobre identificadores o constantes. Los operadores admitidos por Java son:
+
^
<=
++
%=
>>>=
-
~
>=
-
&=
.
*
&&
<< 
==
<<=
[
/
||
>> 
+=
^=
]
%
!
>>> 
=
!=
(
&
< 
*=
)
|
> 
?!!
/=
>> 

Tabla 3: Operadores Java
Así por ejemplo el siguiente fragmento de código incrementa el valor de una variable en dos unidades, mediante la utilización del operador aritmético + que se utiliza para la suma:
int miNumero=0;
miNumero = miNumero + 2;
En el apartado "II.3 Operadores" de este tutorial aprenderemos que en Java hay formas más sencillas de hacer esto mismo, y estudiaremos el significado de cada uno de estos operadores.
e.) Separadores
Se usan para informar al compilador de Java de cómo están agrupadas las cosas en el código.
Los separadores admitidos por Java son: { } , : ;
f.) Comentarios y espacios en blanco
El compilador de Java reconoce y elimina los espacios en blanco, tabuladores, retornos de carro y comentarios durante el análisis del código fuente.
Los comentarios se pueden presentar en tres formatos distintos:
Formato
Uso
/*comentario*/
Se ignoran todos los caracteres entre /* */. Proviene del C
//comentario
Se ignoran todos los caracteres detrás de // hasta el fin de línea. Proviene del C++
/**comentario*/
Lo mismo que /* */ pero se podrán utilizar para documentación automática.
Tabla 4: Formatos de comentarios Java
Por ejemplo la siguiente línea de código presenta un comentario:
int alturaMinima = 150; // No menos de 150 centímetros
Expresiones
Los operadores, variables y las llamadas a métodos pueden ser combinadas en secuencias conocidas como expresiones. El comportamiento real de un programa Java se logra a través de expresiones, que se agrupan para crear sentencias.
Una expresión es una serie de variables, operadores y llamadas a métodos (construida conforme a la sintaxis del lenguaje) que se evalúa a un único valor.
Entre otras cosas, las expresiones son utilizadas para realizar cálculos, para asignar valores a variables, y para ayudar a controlar la ejecución del flujo del programa. La tarea de una expresión se compone de dos partes: realiza el cálculo indicado por los elementos de la expresión y devuelve el valor obtenido como resultado del cálculo.
Los operadores devuelven un valor, por lo que el uso de un operador es una expresión.
Por ejemplo, la siguiente sentencia es una expresión:
int contador=1;
contador++;
La expresión contador++ en este caso particular se evalúa al valor 1, que era el valor de la variable contador antes de que la operación ocurra, pero la variable contador adquiere un valor de 2.
El tipo de datos del valor devuelto por una expresión depende de los elementos utilizados en la expresión. La expresión contador++ devuelve un entero porque ++ devuelve un valor del mismo tipo que su operando y contador es un entero. Otras expresiones devuelven valores booleanos, cadenas...
Una expresión de llamada a un método se evalúa al valor de retorno del método; así el tipo de dato de la expresión de llamada a un método es el mismo que el tipo de dato del valor de retorno de ese método.
Otra sentencia interesante sería:
in.read( ) != -1 // in es un flujo de entrada
Esta sentencia se compone de dos expresiones:
  1. La primera expresión es una llamada al método in.read(). El método in.read() ha sido declarado para devolver un entero, por lo que la expresión in.read() se evalúa a un entero.
  2. La segunda expresión contenida en la sentencia utiliza el operador !=, que comprueba si dos operandos son distintos. En la sentencia en cuestión, los operandos son in.read() y -1. El operando in.read() es válido para el operador != porque in.read() es una expresión que se evalúa a un entero, así que la expresión in.read()!=-1 compara dos enteros. El valor devuelto por esta expresión será verdadero o falso dependiendo del resultado de la lectura del fichero in.
Como se puede observar, Java permite construir sentencias (expresiones compuestas) a partir de varias expresiones más pequeñas con tal que los tipos de datos requeridos por una parte de la expresión concuerden con los tipos de datos de la otra.
Bloques y ámbito
En Java el código fuente está dividido en partes separadas por llaves, denominas bloques. Cada bloque existe independiente de lo que está fuera de él, agrupando en su interior sentencias (expresiones) relacionadas.
Desde un bloque externo parece que todo lo que está dentro de llaves se ejecuta como una sentencia. Pero, ¿qué es un bloque externo?. Esto tiene explicación si entendemos que existe una jerarquía de bloques, y que un bloque puede contener uno o más subbloques anidados.
El concepto de ámbito está estrechamente relacionado con el concepto de bloque y es muy importante cuando se trabaja con variables en Java. El ámbito se refiere a cómo las secciones de un programa (bloques) afectan el tiempo de vida de las variables.
Toda variable tiene un ámbito, en el que es usada, que viene determinado por los bloques. Una variable definida en un bloque interno no es visible por el bloque externo.
Las llaves de separación son importantes no sólo en un sentido lógico, ya que son la forma de que el compilador diferencie dónde acaba una sección de código y dónde comienza otra, sino que tienen una connotación estética que facilita la lectura de los programas al ser humano.
Así mismo, para identificar los diferentes bloques se utilizan sangrías. Las sangrías se utilizan para el programador, no para el compilador. La sangría (también denominada indentación) más adecuada para la estética de un programa Java son dos espacios:




No hay comentarios:

Publicar un comentario