Principales Características
de JAVA.
Java es un lenguaje de programación
de propósito general orientado a objetos desarrollado por Sun Microsystems.
También se puede decir que Java es una tecnología que no
sólo se reduce al lenguaje sino que además provee de una
máquina virtual Java que permite ejecutar código compilado
Java, sea cual sea la plataforma que exista por debajo; plataforma tanto
hardware, como software (el sistema operativo que soporte ese hardware).
El apoyo a esta tecnología viene dado por la gran cantidad de fabricantes
que apoyan esta especificación de máquina virtual.
Aprender el lenguaje de programación
Java requiere tiempo y esfuerzo, pero en este curso trataremos de sentar
las bases para el conocimiento general del lenguaje. El lenguaje se inspira
en otros lenguajes:
-
sentencias comunes de C y C++ (sintaxis
parecida a dichos lenguajes)
-
concurrencia parecida a la de Mesa (un
lenguaje de investigación de Xerox)
-
interrupciones parecidas a las de Modula-3
-
tratamiento de enlace dinámico de
código nuevo parecido al de Lisp
-
definiciones de interfaces parecidas a
las de Objective C
-
gestión de almacenamiento automático
parecida a la de Lisp
Características.
Sun describe al lenguaje Java de la siguiente
manera:
-
Simple
-
Orientado a Objetos
-
Tipado estáticamente
-
Distribuido
-
Interpretado
-
Robusto
-
Seguro
-
de Arquitectura Neutral
-
Multihilo
-
con Recolector de basura (Garbage Collector)
-
Portable
-
de Alto Rendimiento: sobre todo con la
aparición de hardware especializado y mejor software
-
Dinámico
Sun admite que lo dicho anteriormente son
un montón de halagos por su parte, pero el hecho es que todas esas
caraterísticas pueden servir para describir el lenguaje. Todas ellas
son importantes, sin embargo cabe destacar tres, que son las que han propocionado
tanto interés por el lenguaje: la portabilidad, el hecho de que
sea de arquitectura neutral y su simplicidad. Java ofrece toda la funcionalidad
de los lenguajes potentes, pero sin las características menos usadas
y más confusas de éstos.
Java elimina muchas de las características
de otros lenguajes como C++, para mantener reducidas especificaciones del
lenguaje y añadir características muy útiles como
el recolector de basura. No es necesario preocuparse de liberar memoria,
el recolector se encarga de eliminar la memoria asignada. Gracias al recolector,
sólo te tienes que preocupar de crear los objetos relevantes de
tu sistema ya que él se encarga de destruirlos en caso de no ser
reutilizados.
Java reduce en un 50% los errores más
comunes de programación con lenguajes como C y C++. Entre las características
más "indeseables" de C++ que se han evitado en el diseño
de Java destacan: ficheros de cabecera, aritmética de punteros,
sobrecarga de operadores, estructuras, uniones, conversión implícita
de tipos, clases base virtuales, pre-procesador, etc.
Comentemos algunas de las características
más interesantes:
Java es interpretado.
Estrictamente hablando, Java es interpretado,
aunque en realidad Java es tanto interpretado como compilado. De hecho,
sólo cerca del 20% del código Java es interpretado por la
JVM (Java Virtual Machine), pero es un 20% muy importante. Tanto la seguridad
de Java como su habilidad para ser ejecutado en múltiples plataformas
se deben a que los pasos finales de la compilación se manejan localmente.
Existen ciertos entornos que para mejorar
el rendimiento usan un pequeño compilador para la última
fase de compilación, de forma que una vez que se tenga el bytecode,
en vez de interpretarlo se compila generando código nativo para
esa plataforma y se ejecuta, pero esta compilación se realiza cada
vez que se quiera ejecutar el programa. El único código realmente
independiente es el bytecode. Este tipo de compiladores se conocen como
'Just In Time' o JIT. Sin embargo, el bytecode no se completa hasta que
se junta con un entorno de ejecución, que en este caso será
la máquina virtual Java de la plataforma en la que estemos. Un browser
puede proveer dicha plataforma desde el punto de vista del sistema operativo.
Inconvenientes.
El browser tiene que interpretar los
ficheros de clases antes de que se ejecuten. Utilizando un lenguaje de
programación tradicional como puede ser el C++, el ordenador puede
ejecutar directamente el código generado. Sin embargo, debido a
la interpretación que el browser tiene que hacer de los ficheros,
los programas escritos en Java tienden a ejecutarse bastante más
lentos que con otros lenguajes de programación (p.e. C++).
¿Por qué se considera
un rasgo positivo el hecho de combinar la compilación y la interpretación?
-
Facilita la seguridad y la estabilidad.
-
Reduce los problemas de versiones.
El hecho de que la última fase de
la compilación se lleve a cabo por un dispositivo de una determinada
plataforma, releva al programador de la responsabilidad del mantenimiento
de varios fuentes en varias plataformas. La interpretación también
admite que los datos se incorporen en tiempo de ejecución, de ahí
el comportamiento dinámico que también caracteriza a Java.
La máquina virtual
Java.
Para establecer Java como parte integral
de la red, el compilador Java 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
(runtime) puede ejecutar ese código objeto, sin importar en modo
alguno la máquina en que ha sido generado.
El código fuente Java se "compila"
a un código de bytes de alto nivel independiente de la máquina.
Este código (bytecode) está diseñado para ejecutarse
en una máquina hipotética que es implementada por un sistema
runtime, que sí es dependiente de la máquina. Por lo tanto,
lo que verdaderamente es dependiente del sistema es la Máquina Virtual
Java (JVM) y las librerías fundamentales, que también nos
permitirían acceder directamente al hardware de la máquina.
El compilador Java genera bytecode que serán ejecutables dondequiera
que exista una JVM.
Orientación
a objetos.
Java implementa la tecnología básica
de C++ con algunas mejoras y elimina algunas cosas para mantener el objetivo
de la simplicidad del lenguaje. Java trabaja con sus datos como objetos
y con interfaces a esos objetos. Soporta las tres características
propias del paradigma de la orientación a objetos: encapsulación,
enlace dinámico y polimorfismo. Los modelos de objetos son llamados,
como en C++, clases y sus copias, instancias. Estas instancias, como en
C++, necesitan ser construidas y destruidas en espacios de memoria.
Java incorpora funcionalidades inexistentes
en C++ como por ejemplo, la resolución dinámica de métodos.
Esta característica deriva del lenguaje ObjectiveC. En C++ se suele
trabajar con librerías dinámicas (DLLs) que obligan a recompilar
la aplicación cuando se retocan las funciones que se encuentran
en su interior. Java resuelve este inconveniente mediante una interfaz
específica llamada RTTI (Run Time Type Identification) que define
la interacción entre objetos excluyendo variables de instancias
o implementación de métodos. Las clases en Java tienen una
representación en el runtime que permite a los programadores interrogar
por el tipo de clase y enlazar dinámicamente la clase con el resultado
de la búsqueda.
En Java casi todo son objetos. La mayoría
de los lenguajes orientados a objetos permiten la herencia múltiple,
lo que puede llevar a confusiones y/o complicaciones innecesarias. Java
no permite herencia múltiple, sólo soporta "Herencia simple"
en una estructura cósmica (todas las clases Java derivan jerárquicamente
de la clase "Object"). La herencia simple significa que en cada momento
cada clase sólo hereda de otra clase. Este tipo de herencia evita
problemas del tipo de herencias múltiples contradictorias o exclusivas
entre sí.
Java también permite la creación
de clases totalmente abstractas, a las que llama interfaces con características
similares a los interfaces IDL de CORBA. Las interfaces permiten definir
métodos que
pueden compartir con varias clases,
sin tener en cuenta cómo las otras manejan los métodos.
Seguridad en JAVA.
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 bytecodes 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-.
Si los bytecode pasan la verificación
sin generar ningún mensaje de error, entonces sabemos que:
-
El código no produce desbordamiento
de operandos en la pila
-
El tipo de los parámetres de todos
los códigos de operación son conocidos y correctos
-
No ha ocurrido ninguna conversión
ilegal de datos, tal como convertir enteros en puntero
-
El acceso a los campos de un objeto se
sabe que es legal: public, private, protected
-
No hay nungún intento de violar
las reglas de acceso y seguridad establecidas
-
Evitamos saltos a mitad de una instrucción,
o direccionamientos de memoria de un objeto fuera de los límites
del mismo.
El cargador de clases también ayuda
a Java a mantener su seguridad, separando el espacio de nombres del sistema
de ficheros local, del de los recursos procedentes de la red. Esto limita
cualquier aplicación del tipo Caballo de Troya, ya que las clases
se buscan primero entre las locales y luego entre las procedentes del exterior.
Definición de
API.
API son las iniciales de Application Programmer
Interface. Pensemoslo siguiente. Por muy completo que sea un lenguaje en
cuanto a estructuras, tipos de datos y operadores, para que sea funcional
necesita hacer E/S (procesar ficheros, pedir datos por teclado, leer el
ratón o visualizar ventanas). La E/S es dependiente del Sistema
Operativo. La API es una capa de abstracción que se pone encima
del S.O. para permitir hacer entradas y salidas de una manera estandarizada.
Se trata de una especificación de una librería software,
detallando las llamadas a funciones, los argumentos, y los resultados que
obtienes al utilizarlas. Una API sólo existe en papel y no es más
que diseño. De hecho, para usar una API necesitas una librería
que exista y que implemente esa API.
Clasificación de las APIs
Las APIs están clasificadas como
API Core (Núcleo) o como Standard Extension (Extensiones estándar).
Una API Core es aquélla que viene incluida en el sistema JDK, es
parte de la implementación estándar de Sun y cualquier sistema
Java tiene que ser capaz de soportarlas. Una extensión estándar
es una librería que los sistemas Java no tienen por qué soportar,
pero de hacerlo, lo tiene que hacer siguiendo exactamente la forma estándar.