• Últimas noticias

    6. Características de JAVA

    Sexto episodio del curso de Java.

    Ya hemos hablado mucho sobre varias características de JAVA, pero sin entrar mucho en detalle. Llego el momento en que debemos analizar y estudiar todas las características que nos brinda este gran lenguaje.


    índice de este curso


    Versión de este curso en video


    Si querés podés ver el video correspondiente a este curso


    Introducción

    Java es un lenguaje utilizado por millones de desarrolladores, y esto es gracias a las prestaciones y características del mismo.

    El lenguaje Java se creó con cinco objetivos principales:
    1- Ser fácil de usar y tomar las mejores características de lenguajes como C y C++
    2- Usar el paradigma orientado a objetos en su totalidad
    3- Permitir la ejecución de un programa en múltiples plataformas
    4- Incluir por defecto soporte para trabajar en red
    5- Ser seguro para su ejecución en sistemas remotos/div>

    Facilidad de uso

    Java se creó porque C y C++ que eran los lenguajes que utilizaban a mediados de los años 80, no eran totalmente convincentes para abordar temas de seguridad, pero en esa época, eran los lenguajes más utilizados, incluso hoy en día siguen siendo los lenguajes más utilizados, por lo cual todo el mundo que sabía programar sabia C o C++, es por esto que se basaron en la sintaxis de estos lenguajes, y de esta manera hacer que a cualquier persona que quisiera aprender Java le resulte fácil.

    Además de esto Java elimina las funcionalidades menos utilizadas por estos lenguajes y también las más confusas, haciendo que programar en Java resulte más simple desligando al programador de ciertas tareas tediosas que de otro modo tenían que realizar a mano. Por ejemplo una de las características más destacadas que se ha eliminado es la del manejo de punteros, mientras que en C este manejo lo realizaba el programador, en Java lo administra el propio lenguaje.

    Paradigma orientado a objetos (POO)

    Java utiliza el paradigma orientado a objetos. El paradigma orientado a objetos es el paradigma predominante en la actualidad, y sin ahondar mucho en detalles, ya que sería absurdo comentar las características del paradigma que haga que Java se destaque sin haber explicado todavía este paradigma, podemos decir que permite construir grandes sistemas de una forma modularizada de manera que sean fáciles de gestionar y manejar, mejorando su calidad y reduciendo el número de proyectos fallidos. Además este paradigma permite la reutilización de código entre diferentes proyectos, lo que hace mucho más simple la implementación de ciertos módulos ya programados anteriormente en un nuevo sistema.

    Soporte para trabajar en red

    Otra característica importante de Java es el soporte que ofrece para trabajar en red. Para eso se abstrajeron las características y detalles específicos en referencia a los aspectos técnicos de redes de comunicaciones. Con el objetivo de simplificar la tarea del programador a la hora de trabajar con redes a bajo nivel, Java proporciona formas básicas de trabajar en red mediante Sockets y URL
    En base a esto se desprende la característica de que Java proporciona librerías y herramientas para que los programas puedan ser distribuidos, y que gracias a la capacidad que tiene para realizar conexiones con protocolos TCP, UDP, HTTP y FTP, permite el acceso de la información a través de la red con tanta facilidad de cómo se accede a los datos de un archivo.

    Multiplataforma

    Como ya hemos nombrado montones de veces una de las características clave del lenguaje es que sus programas sean multiplataforma. Esto permite que un programa sea ejecutado casi en cualquier dispositivo y es muy útil en relación a aplicaciones en red, ya que un mismo programa podría ejecutarlo en una computadora con Windows y en un Servidor con sistema operativo Solaris, sin tener que escribirlo dos veces, o sea, una vez por cada plataforma.

    Seguridad

    Una característica completamente controversial es la seguridad de Java. Java se destaca, en teoría, por ser un lenguaje extremadamente seguro.
    En esta parte vamos a tener que extendernos un poco para poder comprender el tema.
    En primer lugar se eliminan los punteros y el casting implícito de tipos que realiza el compilador de C y C++. Esto evita accesos ilegales a memoria. Si se pudiera acceder a cualquier posición de memoria como se hace con los punteros de C, se podría acceder a alguna posición de memoria conocida y extraer datos que pudieran ser confidenciales, o bien alterarlos. 
    Incluso otra falencia en C y C++ es la fácil inserción de un troyano en sus programas, haciendo que la persona que haya hecho pasar este programa malicioso tenga acceso a todos los archivos del sistema. En Java, esto se soluciona mediante varias pruebas que se realizan antes de que el programa sea ejecutado en un dispositivo. El código se pasa a través de un verificador de ByteCode que comprueba el formato de los fragmentos de código y aplica un probador de teoremas para detectar fragmentos de código ilegal.

    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 lo que imposibilita que una clase suplante a una ya predefinida.

    Por tanto, un programa en java no accede a zonas delicadas de memoria o de sistemas de almacenamiento, e implementa además, por si se quisiera acceder a algún archivo del sistema, un método ultra seguro de autentificación por clave pública. Esto quiere decir que permitirá solo la ejecución de programas que estén firmados digitalmente por una entidad certificadora conocida, y en otro caso, preguntará si realmente desea ejecutar el programa, siendo que al no estar firmado, las consecuencias de lo que pueda pasar con el mismo corren bajo su propio riesgo, un sistema parecido al que usa MacOS para mantener su sistema libre de aplicaciones maliciosas.

    Además de imposibilitar abrir ficheros de la máquina local, Java evita que se puedan ejecutar aplicaciones nativas de una plataforma e impide que se utilicen otras computadoras como puente, es decir, que nadie puede utilizar nuestra computadora para hacer peticiones o realizar operaciones con otra.

    Entonces, donde está la controversia en la seguridad de las aplicaciones hechas en Java si por lo visto, Java construye un entorno ultra seguro.

    Se pueden leer montones de artículos que alegan sobre fallas de seguridad en Java que permiten acceder ilegalmente a un sistema, y en realidad no se debe a un fallo de seguridad de Java sino que se trata de un fallo de seguridad en los navegadores y en cómo se hace la implementación de los applets en ellos, un tema recurrente que se da desde los orígenes de este lenguaje del que ya hablamos en el apartado de la historia de Java

    Si bien Java está encerrado en lo que se conoce como un SandBox que en español se define como entorno aislado, concepto que refiere al hecho de evitar que el programa pueda acceder a otras zonas de memoria, disco, recursos de red, etc, sabemos que Java puede saltarse las restricciones si la aplicación esta certificada por una entidad válida o también puede haber un fallo de diseño del propio lenguaje que lo permita.

    Por lo tanto ¿Java es inseguro?

    No, pero por desgracia los complementos en los navegadores fallan. Si Java fuera un lenguaje inseguro no sería utilizado por empresas como Netflix, Twitter, Facebook, Amazon, Uber, Google, Android, Ebay, y un largo etcétera.

    Seguridad del código de fuente

    En las herramientas que nos brinda el JDK, existe la herramienta Javap que sirve para desensamblar archivos .class. Esto quiere decir que el programa que pueda llegar a desarrollar puede ser desensamblado por cualquier persona. Podríamos bajar algún juego por ejemplo de GameLoft, empresa Francesa conocida por desarrollar una gran cantidad de aplicaciones para celulares especialmente hechas en Java, desensamblarlo y ver todo su código.

    ¿Hay alguna manera de asegurar mi código para evitar que cualquier persona tenga acceso al mismo?

    La respuesta es mas o menos.

    Una forma de aislar completamente mi código es hacer que mi programa adopte la forma de cliente-servidor. Donde todo el código importante lo tendríamos en el servidor, y el código del cliente solo servirá para comunicarse con la aplicación del servidor. De esta manera se puede alejar las manos de cualquiera de nuestro código, con el costo de que para ejecutar la aplicación se debe contar si o si con una conexión a Internet.

    Otra forma sería cifrar los archivos de clase, teniendo en cuenta que antes de la ejecución del programa necesitaremos descifrar los mismos, dejando un trabajo bastante fácil a los hackers.

    Un tercer método consistiría convertir nuestro programa a código nativo, lo que quitaría la característica al programa de ser multiplataforma, y que aunque con éste método dificultaremos más la tarea de decompilar el programa, no la evitaríamos totalmente. Piensen solo en que videojuegos desarrollados por super compañías multimillonarias son crackeados tiempo después de su lanzamiento.

    Otro método consiste en lo que se llama Ofuscación del código. La Ofuscación de código consiste en modificar el código para que su comprensión sea muy difícil y al mismo tiempo cumpla la misma función que el código original. La ofuscación perfecta es imposible pero puede complicarle bastante la vida a quien esté analizando nuestro programa.


    Programa ofuscado en C que implementa una calculadora científica. Fuente: hou @ IOCCC 2011 – Licencia: CC BY-SA 3.0

    Robusto

    Un lenguaje robusto refiere a un lenguaje fuerte, y particularmente en informática refiere a la capacidad de un sistema informático de hacer frente a los errores durante la ejecución, así también como el buen manejo de excepciones, entendiendo por esto a capturar y resolver errores imprevistos en tiempo de ejecución.

    Java realiza verificaciones tanto en tiempo de compilación como en tiempo de ejecución para la detección de errores, provee de un sistema de control de tipos que evita que por ejemplo se sumen números con cadenas, libera al programador de la tarea de manejar memoria manualmente lo que evita errores por corrupción de memoria, implementa chequeos en arrays para evitar que se acceda a una posición inexistente del mismo, y brinda un control completo de excepciones.

    Flexible

    Además de ser Robusto es un lenguaje flexible. Java combina flexibilidad, robustez y legibilidad. Si bien Java es un lenguaje de tipado fuerte, existe la posibilidad de declarar atributos del tipo Object, que dicho de otra manera, quiere decir que pueden tomar cualquier forma, o mejor dicho ser de cualquier tipo. Asimismo se pueden realizar conversiones entre tipos mediante métodos de casteo provistos por el lenguaje. El programador por tanto utiliza tipos específicos para ganar legibilidad, mientras que en algunos casos donde debe tratar con algún tipo de dato desconocido utiliza el tipo de dato Object a fin de ganar flexibilidad.

    Multihilo

    Java es un lenguaje que permite hacer aplicaciones multihilo. Una aplicación multihilo es aquella que tiene la capacidad de ejecutar varios procesos al mismo tiempo. Esto quiere decir que podemos programar una aplicación y que mientras un hilo muestra una pantalla para interactuar con el usuario, otro hilo se encarga de realizar la conexión con el servidor en paralelo, otro hilo se encarga de realizar cálculos, etc.

    Un ejemplo pueden ser los navegadores web, en donde no hay que esperar que cargue una página entera para poder visualizarla. El usuario puede navegar por la página web por más que la misma no haya cargado todas las imágenes que contiene. Esto es porque un hilo de ejecución paralelo se encarga de cargar las imágenes, mientras otro hilo nos muestra el resto del contenido de la página web.

    Enlace dinámico

    La interpretación del código o la tecnología utilizada por el compilador Just in Time permite que los datos se incorporen en tiempo de ejecución. Esto quiere decir que las clases de java solo son enlazadas cuando son necesitadas y que también se puedan enlazar nuevos módulos de código bajo demanda procedentes de fuentes muy variadas,  incluso desde la red. Por ejemplo:

    Si desarrollo un videojuego en Java, podría tener una clase que corresponde al menú del juego, y otra clase que corresponde al juego en sí una vez iniciada la partida Al ejecutar el programa, el compilador JIT enlazará la clase correspondiente al menú, y no será hasta que inicie el juego, cuando la clase correspondiente al juego en sí sea enlazada.

    En el caso de que se enlacen librerías nuevas o actualizadas no se paralizará la ejecución de las aplicaciones actuales -siempre que mantengan el API anterior.

    Acá es necesario frenar un poco para entender que es un API.  De paso nos servirá también para entender el caso de Oracle vs Google que ha sido mencionado en el apartado de la historia de Java. 

    API

    API es el acrónimo de Application Programming Interfaz o Interfaz de programación de aplicaciones en español. Para explicar que es un API debemos retornar al concepto de JDK, el cual es, según dijimos, un conjunto de herramientas y librerías que sirven para poder desarrollar y ejecutar programas en Java. Bien, nosotros detallamos algunas de las herramientas pero no hablamos nunca de librerías, y cuando hablamos de librerías nos referimos a un conjunto de clases o archivos que contienen funciones útiles para el desarrollo de nuestro programa.

    Por ejemplo, para mostrar un mensaje en la consola de java llamamos a una función llamada println, y dicha función está incluida en una clase que está dentro de la API de Java. Así como funciones para mostrar mensajes por consola, existen otras para pedir datos al usuario, para manejar archivos, conexiones de red, mostrar ventanas e interfaces gráficas, realizar operaciones matemáticas y muchísimas más.

    Hay que tener en cuenta que la API se actualiza con cada versión nueva de Java proveyéndonos de nuevas clases, nuevas funciones y en algunos casos dejando obsoletas funciones de APIs anteriores, que retomando el tema, la obsolescencia de estas funciones no paralizarán la ejecución de las aplicaciones actuales -siempre que mantengan el API anterior.

    Rápido

    Java es Rápido. Sí, como lo leen, java es rápido. Otra característica que puede causar gran controversia por la cantidad de personas y sitios web que dicen que Java no es un lenguaje rápido en comparación de lenguajes como por ejemplo C, pero la realidad es que desde que Java implemento un compilador Just in Time en su maquina virtual, la velocidad de ejecución de sus aplicaciones son casi tan rápidas como un programa hecho en C, y no digo esto por vender ningún producto ya que no trabajo en Java ni me pagan por hacerles publicidad, sino que a los hechos me remito, y basándonos en documentos de investigación que realizaron ingenieros de diferentes universidades de Portugal, en donde comparan la eficiencia de 27 lenguajes de programación, podemos encontrar a Java como el cuarto lenguaje más rápido, siendo el primero C, y que si nos basamos en las tablas que utilizan ciertos algoritmos para determinar la eficiencia de cada lenguaje se puede ver que en uno de los casos Java tarda algo así 276 milisegundos más que C en ejecutar una serie de instrucciones.


    Garbage collector

    Un elemento estrella es el conocido garbage collector o recolector de basura de Java. Si bien no fueron los que lo inventaron, si fueron los que lo implementaron bien, y si bien hay que conocer un poco más del paradigma orientado a objetos para entender esta característica vamos a resumirla diciendo que es un programa que está todo el tiempo analizando la memoria a fin de localizar objetos en la misma que ya no se usen para eliminarlos. Podemos hacer una analogía para que se entienda un poco el concepto del recolector de basura sin necesidad de saber los conceptos del paradigma orientado a objetos.

    Supongamos que creo una variable de tipo entera, y que sirve para almacenar la edad del usuario. Al comienzo de mi programa le pido al usuario que ingrese su edad, y si el mismo es mayor de 18 años procedo a ejecutar el programa, el cual puede estar mucho tiempo en ejecución.
     int edad;
     println("Ingrese su edad");
     edad = scanValue();
     if(edad>=18){
        //Código de mi programa
     }
    
    

    Esta variable no la voy a usar nunca más en mi programa, pero sin embargo el valor seguirá cargado en memoria ocupando un espacio en ella. El recolector de basura detecta este tipo de variables que se encuentran en memoria, y que ya no serán utilizadas, y las elimina a fin de evitar fugas de memoria,  problema que puede aparecer en lenguajes como C++ ya que el programador puede olvidar liberar bloques de memoria que ya no estén siendo utilizados. Además de evitar fugas de memoria es un gran aporte para la productividad del programador, ya que  se han estudiado casos concretos en donde los programadores han dedicado un 40% del tiempo de desarrollo para determinar en qué momento se puede liberar un bloque de memoria.

    Comunidad de desarrolladores

    Para terminar con el tema de las características que nos brinda Java no podemos dejar de nombrar a la gran comunidad de desarrolladores del lenguaje. Los millones de desarrolladores que trabajan con Java conforman una comunidad de desarrollo que aportan infinidad de bibliotecas y utilidades para extender la funcionalidad y mejorar la plataforma de Java. Casi cualquier cosa que se pueda llegar a necesitar seguramente ya estará desarrollada en algún proyecto de código abierto, y lo mejor de todo es que muchas bibliotecas conocidas y utilizadas las mantienen Google, Facebook, Apache y Amazon que nos provee de un JDK personalizado el cual está dirigido y supervisado personalmente por James Gosling.

    Esto nos facilita mucho la vida como programadores y no existen muchas comunidades que puedan brindar la misma cantidad de código utilizable. 

    Conclusión
    Es por todo esto que Java es un lenguaje tan popular y utilizado por tantas personas y organizaciones importantes. Aprender Java hará que puedan conseguir en trabajo casi en cualquier lugar, ya que la demanda de empleo es gigante y resultará útil para conocer muchas características, que nos darán un mejor entendimiento no solo de Java, sino también de otros lenguajes, lo cual es sumamente beneficioso ya que como programadores no debemos casarnos con un lenguaje, sino tener las herramientas necesarias para poder elegir el lenguaje adecuado según lo que se necesite desarrollar.

    En la próxima entrega veremos como instalar Java y el entorno de desarrollo Eclipse.


    ANTERIOR
    5. La máquina virtual de JAVA
    SIGUIENTE
    6. Instalación de JAVA y Eclipse

    Autor: Pablo Jasinski

    Profesor en Escuela Técnica UBA y Escuela Técnica Nº35, especializado en materias de programación, arquitectura de las computadoras y redes. Profesional en el área de programación y desarrollo de videojuegos.

    No hay comentarios