Archivos para la categoría ‘Tutorial’

Tutorial. Qué es un paquete

26 de Agosto de 2008

Un paquete es un espacio de nombres que organiza un conjunto de clases e interfaces relacionadas. Puede pensar en los paquetes como algo similar a las diferentes carpetas de su ordenador. Puede tener guardadas páginas HTML en una carpeta, imágenes en otra y scripts y aplicaciones en otra distinta. Puesto que un software escrito en el lenguaje de programación Java puede llegar a consistir de cientos o miles de clases individuales, tiene sentido que se organicen las clases e interfaces relacionadas en paquetes.

La plataforma Java proporciona una enorme biblioteca de clases (un conjunto de paquetes) adecuado para usar en sus propias aplicaciones. A esta biblioteca se la conoce como la Interfaz de Programación de Aplicaciones (Application Programming Interface en inglés) o por su abreviatura API. Sus paquetes representan las tareas más comunes asociadas a la programación en general. Por ejemplo, un objeto String contiene estado y comportamiento para cadenas de caracteres («character strings»); un objeto File permite a un programador crear, eliminar, inspeccionar, comparar o modificar un archivo en un sistema de archivos; un objeto Socket permite la creación y uso de sockets de red; otros objetos de interfaz gráfica («GUI») controlan botones, cajas de selección y cualquier otra cosa relacionada con las interfaces gráficas de usuario. Literalmente hay miles de clases de las que elegir. Esto le permite al programador enfocar sus esfuerzos en el diseño de la aplicación, más que en la infraestructura requerida para hacerla funcionar.

La Java Platform API Specification contiene el listado completo de todos los paquetes, interfaces, clases, campos y métodos proporcionados por la Plataforma Java 6, edición estándar (Java Platform 6, Standard Edition). Cargue esta página en su navegador y añádala a sus marcadores o favoritos. Siendo programador se convertirá en su documentación de referencia más importante.

 

Tutorial. Qué es un interfaz

25 de Agosto de 2008

Como ya ha aprendido, los objetos definen su interacción con el mundo exterior a través de los métodos de que exponen. Los métodos forman la interfaz del objeto con el mundo exterior; por ejemplo, los botones que hay en la parte frontal de su televisor forman la interfaz entre usted y el cableado eléctrico al otro lado de la caja de plástico. Debe pulsar un botón para encender y apagar el televisor.
En su forma más común, una interfaz es un grupo de métodos relacionados con cuerpos vacíos. El comportamiento de una bicicleta, si se especifica como una interfaz, podría aparecer así:

interface Bicycle {
 
       void changeCadence(int newValue);
 
       void changeGear(int newValue);
 
       void speedUp(int increment);
 
       void applyBrakes(int decrement);
}

Para implementar esta interfaz el nombre de su clase debería cambiar (a ACMEBicycle, por ejemplo), y usaría la palabra clave implements en la declaración de clase:

class ACMEBicycle implements Bicycle {
 
   // remainder of this class implemented as before
 
}

Implementar una interfaz permite a una clase ser más formal acerca del comportamiento que promete proporcionar. Las interfaces forman un contrato entre la clase y el mundo exterior, y este contrato se hace cumplir en el momento de la compilación. Si su clase afirma implementar una interfaz, todos los métodos definidos por esa interfaz deben aparecer en su código fuente para que se compile con éxito.

Tutorial. Qué es la herencia

21 de Agosto de 2008

A menudo diferentes tipos de objetos tienen algunas cosas en común. Por ejemplo, las bicicletas de montaña, las de carretera y los tándems todos comparten las características de las bicicletas (velocidad actual, cadencia de pedal, marcha). Aún así cada una de ellas también define características adicionales que las hacen diferentes: los tándems tienen dos asientos y dos manillares, las bicicletas de carretera tienen un manillar con cuernos, algunas bicicletas de montaña tienen más piñones que les proporcionan marchas más cortas.

La programación orientada a objetos permite que las clases hereden estados y comportamientos de uso común de otras clases. En este ejemplo, Bicycle se convierte en la superclase de MountainBike, RoadBike y TandemBike. En el lenguaje de programación Java se permite que cada clase tenga una superclase directa y que cada superclase tenga el potencial para una cantidad ilimitada de subclases.

La sintaxis para crear subclases en sencilla. Utilice la palabra clave extends seguida del nombre de la clase de la que desea heredar al inicio de su declaración de clase:

class MountainBike extends Bicycle {
 
     // Los nuevos campos y métodos que definan una bici de montaña irían aquí
 
}

Esto proporciona a MountainBike los mismos campos y métodos que Bicycle, pero permite a su código encargarse exclusivamente de las características que la hacen única. Esto hace que el código de sus subclases sea fácil de leer. Sin embargo debe encargarse de documentar apropiadamente el estado y comportamiento que cada superclase que define, ya que ese código no aparecerá en el archivo fuente de cada subclase.

Tutorial. Qué es una clase

20 de Agosto de 2008

En el mundo real a menudo se encontrará con muchos objetos individuales del mismo tipo. Puede haber miles de otras bicicletas, todas de la misma marca y modelo. Cada bicicleta ha sido fabricada a partir de los mismos planos y, por lo tanto contiene los mismos componentes. En términos de orientación a objetos decimos que su bicicleta es una instancia de la clase de objetos conocida como bicicletas. Una clase es el plano del que se crean objetos individuales.

La siguiente clase Bicycle es una posible implementación de una bicicleta:

 
/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 
 
class Bicycle {
 
       int cadence = 0;
       int speed = 0;
       int gear = 1;
 
       void changeCadence(int newValue) {
            cadence = newValue;
       }
 
       void changeGear(int newValue) {
            gear = newValue;
       }
 
       void speedUp(int increment) {
            speed = speed + increment;   
       }
 
       void applyBrakes(int decrement) {
            speed = speed - decrement;
       }
 
       void printStates() {
            System.out.println("cadence:"+cadence+" speed:"+speed+" gear:"+gear);
       }
}

La sintaxis del lenguaje Java le podrá resultar nueva, pero el diseño de esta clase está basada en la anterior discusión sobre los objetos bicicleta. Los campos cadence (cadencia), speed (velocidad) y gear (marcha) representan el estado del objeto, y los métodos (changeCadence, changeGear, speedUp etc.) definen su interacción con el mundo exterior.

Quizás se habrá fijado en que la clase Bicycle no contiene un método main. Eso es porque no es una aplicación completa, solamente es el plano para bicicletas que se podría utilizar en una aplicación. La responsibilidad de crear y usar nuevos objetos Bicycle pertenece a otra clase de su aplicación.

A continuación hay una clase BicycleDemo que crea dos objetos Bicycle distintos e invoca sus métodos:

/*
 * Copyright (c) 1995 - 2008 Sun Microsystems, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */ 
 
class BicycleDemo {
     public static void main(String[] args) {
 
          // Create two different Bicycle objects
          Bicycle bike1 = new Bicycle();
          Bicycle bike2 = new Bicycle();
 
          // Invoke methods on those objects
          bike1.changeCadence(50);
          bike1.speedUp(10);
          bike1.changeGear(2);
          bike1.printStates();
 
          bike2.changeCadence(50);
          bike2.speedUp(10);
          bike2.changeGear(2);
          bike2.changeCadence(40);
          bike2.speedUp(10);
          bike2.changeGear(3);
          bike2.printStates();
     }
}

La salida de esta prueba muestra la cadencia de pedaleo, velocidad y marcha para las dos bicicletas:
cadence:50 speed:10 gear:2
cadence:40 speed:20 gear:3

Tutorial. Qué es un objeto

19 de Agosto de 2008

Los objetos son la clave para entender la tecnología orientada a objetos. Si mira a su alrededor ahora mismo se encontrará con muchos ejemplos de objetos del mundo real: su perro, su escritorio, su televisor, su bicicleta.

Los objetos del mundo real comparten dos características: Todos tienen estado y comportamiento. Los perros tienen estado (nombre, color, raza, hambriento) y comportamiento (ladrando, buscando, meneando la cola). Las bicicletas también tienen un estado (marcha actual, cadencia de pedaleo actual, velocidad actual) y comportamiento (cambio de marcha, cambio de cadencia de pedaleo, frenar). Identificar el estado y el comportamiento de los objetos del mundo real es una gran ayuda para empezar a pensar en términos de programación orientada a objetos.

Tómese un momento ahora mismo para observar los objetos del mundo real que hay a su alrededor. Para cada uno de los objetos que ve, hágase dos preguntas: “¿En qué posibles estados puede estar este objeto?” y “¿Qué posibles comportamientos puede realizar?”". Asegúrese de escribir sus observaciones. Mientras lo haga, verá que los objetos del mundo real varían en complejidad, su lámpara de escritorio puede tener solo dos estados (encendido y apagado) y dos posibles comportamientos (encender y apagar), pero su radio tendrá más estados (encendido, apagado, volumen actual, emisora actual) y comportamientos (encender, apagar, subir volumen, bajar volumen, buscar y sintonizar). También observará que algunos objetos, a su vez, también contendrán otros objetos. Todas estas observaciones del mundo real son reproducibles en el mundo de la programación orientada a objetos.

Un objeto software.

Los objetos software son conceptualmente similares a los objetos del mundo real: también consisten de estado y comportamiento. Un objeto almacena su estado en campos o atributos (”variables” en algunos lenguajes de programación) y muestra su comportamiento a través de métodos (”funciones” en algunos lenguajes de programación). Los métodos operan sobre el estado interno del objeto y sirven como el mecanismo principal para la comunicación entre objetos. La ocultación del estado interno y requerir que toda interacción se realice a través de los métodos de un objeto se conoce como encapsulación de datos — un principio fundamental de la programación orientada a objetos.

Piense, por ejemplo, en una bicicleta. Al atribuir el estado (velocidad actual, cadencia de pedaleo actual y marcha actual) y proporcionar métodos para cambiar ese estado, el objeto mantiene el control sobre cómo se permite al mundo exterior usarlo. Por ejemplo, si la bicicleta solamente tiene 6 marchas, un método que cambie de marcha podrá rechazar cualquier valor que sea inferior a 1 o superior a 6.

Al agrupar código en objetos software individuales se obtienen ciertos beneficios:

  • Modularidad: El código fuente de un objeto se puede escribir y mantener independientemente del código fuente de otros objetos. Una vez creado, un objeto se puede pasar fácilmente de un lado al otro del sistema.
  • Ocultación de información: Al interactuar solamente con los métodos de un objeto los detalles de su implementación interna permanecen ocultas al mundo exterior.
  • Reutilización de código: Si un objeto ya existe (quizás escrito por otro desarrollador de software), puede utilizar ese objeto en su programa. Esto permite que un especialista implemente / compruebe / depure objetos específicos para una tarea, en los que luego podrá confiar en su propio código.
  • Conectividad y facilidad de depuración: Si un objeto en concreto resulta ser problemático podrá simplemente eliminarlo de su aplicación y “conectar” un objeto distinto para reemplazarlo. Esto es análogo a la reparación de problemas mecánicos en el mundo real. Si rompe un tornillo, reemplaza el tornillo, no la máquina entera.

Sentencias de Control de Flujo en Java

1 de Julio de 2008

Las sentencias de control de flujo determinan el orden en que se ejecutarán las otras sentencias dentro del programa. El lenguaje Java soporta varias sentencias de control de flujo, incluyendo.

  • toma de decisiones     if-else, switch-case
  • bucles     for, while, do-while
  • excepciones     try-catch-finally, throw
  • miscelaneas     break, continue, label:, return

Aquí sólo vamos a tratar las sentencias de tomas de decisiones y los bucles, dejando las excepciones para otra ocasión.

Sentencias de toma de decisiones

  • La sentencia if-else

La sentencia if-else de java proporciona a los programas la posibilidad de ejecutar selectivamente otras sentencias basándose en algún criterio. Esta es la versión más sencilla de la sentencia if: la sentencia gobernada por if se ejecuta si alguna codición es verdadera. Generalmente, la forma sencilla de if se puede escribir así.

if (expresión)
sentencia;

Pero, ¿y si quieres ejecutar un juego diferente de sentencias si la expresión es falsa? Bien, puedes utilizar la sentencia else, que ejecuta la condición opuesta

if (expresión)
sentencia;
else
otrasentencia;

Este uso particular de la sentencia else es la forma de capturarlo todo.

Existe otra forma de la sentecia else, else if que ejecuta una sentencia basada en otra expresión. Como ejemplo, un programa que asigna notas basadas en la puntuación de un examen, un Sobresaliente para una puntuación del 90% o superior, un Notable para el 80% o superior y demás:

int puntuacion;
String nota;
 
if (puntuacion >= 90) {
nota = "Sobresaliente";
} else if (puntuacion >= 80) {
nota = "Notable";
} else if (puntuacion >= 70) {
nota = "Bien";
} else if (puntuacion >= 60) {
nota = "Suficiente";
} else {
nota = "Insuficiente";
}

Una sentencia if puede tener cualquier número de sentencias de acompañamiento else if.

  • La sentencia switch-case

La sentencia switch se utiliza para realizar sentencias condicionalmente basadas en alguna expresión. Por ejemplo, un programa contiene un entero llamado mes cuyo valor indica el mes en alguna fecha, y se quiere mostrar el nombre del mes basándose en su número entero equivalente. Se podría utilizar la sentencia switch de Java para realizar esta tarea.

int mes;
. . .
switch (mes) {
case 1:  System.out.println("Enero"); break;
case 2:  System.out.println("Febrero"); break;
case 3:  System.out.println("Marzo"); break;
case 4:  System.out.println("Abril"); break;
case 5:  System.out.println("May0"); break;
case 6:  System.out.println("Junio"); break;
case 7:  System.out.println("Julio"); break;
case 8:  System.out.println("Agosto"); break;
case 9:  System.out.println("Septiembre"); break;
case 10: System.out.println("Octubre"); break;
case 11: System.out.println("Noviembre"); break;
case 12: System.out.println("Diciembre"); break;
default: System.out.println("No es un mes válido");
break;
}

La sentencia switch evalúa su expresión, en este caso el valor de mes, y ejecuta la sentencia case apropiada.

Decidir cuando utilizar las sentencias if o switch dependen del juicio personal. Se puede decidir cual utilizar basándose en la buena lectura del código o en otros factores. Cada sentencia case debe ser única y el valor proporcionado a cada sentencia case debe ser del mismo tipo que el tipo de dato devuelto por la expresión proporcionada a la sentencia switch.

Otro punto de interes en la sentencia switch son las sentencias break después de cada case. La sentencia break hace que el control salga de la sentencia switch y continúe con la siguiente línea. La sentencia break es necesaria porque las sentencias case se siguen ejecutando hacia abajo. Esto es, sin un break explícito, el flujo de control seguiría secuencialmente a través de las sentencias case siguientes.

Finalmente, puede utilizar la sentencia default al final de la sentencia switch para manejar los valores que no se han manejado explícitamente por una de las sentencias case.

Sentencias de Bucle

  • El bucle while

Una sentencia while realiza una acción mientras se cumpla una cierta condición. La sintaxis general de la sentencia while es.

while (expresión)
sentencia;

Esto es, mientras la expresión sea verdadera, ejecutará la sentencia.

sentencia puede ser una sóla sentencia o puede ser un bloque de sentencias. Un bloque de sentencias es un juego de sentencias legales de java contenidas dentro de corchetes(’{'y ‘}’).

Además de while Java tiene otros dos constructores de bucles que puedes utilizar en tus programas.

  • El bucle for

Puedes utilizar este bucle cuando conozcas los límites del bucle (su instrucción de inicialización, su criterio de terminación y su instrucción de incremento). Por ejemplo, el bucle for se utiliza frecuentemente para iterar sobre los elementos de un array, o los caracteres de una cadena.

 
// a es un array de cualquier tipo
. . .
int i;
int length = a.length;
for (i = 0; i < a.length; i++) {
System.out.println(a[i]);
}

Si sabes cuando estas escribiendo el programa que quieres empezar en el inicio del array, parar al final y utilizar cada uno de los elementos. Entonces la sentencia for es una buena elección. La forma general del bucle for puede expresarse asi.

for (inicialización; terminación; incremento)
sentencias

inicialización es la sentencia que inicializa el bucle. Se ejecuta una vez al iniciar el bucle.

terminación es una sentencia que determina cuando se termina el bucle. Esta expresión se evalúa al principio de cada iteracción en el bucle. Cuando la expreión se evalúa a false el bucle se termina.

Finalmente, incremento es una expresión que se invoca en cada interacción del bucle. Cualquiera (o todos) de estos componentes puden ser una sentencia vacía (un punto y coma).

  • el bucle do-while

Java proporciona otro bucle, el bucle do-while,que es similar al bucle while que se vió al principio, excepto en que la expresión se avalú al final del bucle.

do {
sentencias
} while (Expresión Booleana);

La sentencia do-while se usa muy poco en la construcción de bucles pero tiene sus usos. Por ejemplo, es conveniente utilizar la sentencia do-while cuando el bucle debe ejecutarse al menos una vez.

Tutorial. Clases en Java

23 de Junio de 2008

Las clases son los elementos fundamentales de Java. Todo en Java forma parte de una clase, es una clase o describe como funciona una clase. El conocimiento de las clases es fundamental para poder entender los programas Java.

Todas las acciones de los programas Java se colocan dentro del bloque de una clase o un objeto. Todos los métodos se definen dentro del bloque de la clase, Java no soporta funciones o variables globales. Así pues, el esqueleto de cualquier aplicación Java se basa en la definición de una clase.

Todos los datos básicos, como los enteros, se deben declarar en las clases antes de hacer uso de ellos. La palabra clave import puede colocarse al principio de un fichero, fuera del bloque de la clase. Es necesario declarar explícitamente las clases que se van a utilizar (import) que no estén dentro del paquete (package) al que pertenece la clase.

Los tipos de clases que podemos definir son:

  • abstract: Una clase abstract tiene al menos un método abstracto. Una clase abstracta no se instancia, sino que se utiliza como clase base para la herencia.
  • final: Una clase final se declara como la clase que termina una cadena de herencia. No se puede heredar de una clase final. Por ejemplo, la clase Math es una clase final.
  • public: Las clases public son accesibles desde otras clases, bien sea directamente o por herencia. Son accesibles dentro del mismo paquete en el que se han declarado. Para acceder desde otros paquetes, primero tienen que ser importadas.
  • synchronizable: Este modificador especifica que todos los métodos definidos en la clase son sincronizados, es decir, que no se puede acceder al mismo tiempo a ellos desde distintos threads; el sistema se encarga de controlar la concurrencia. Este mecanismo hace que desde threads diferentes se puedan modificar las mismas variables sin que haya problemas de que se sobreescriban.

Cuando se crea una nueva clase en Java, se puede especificar el nivel de acceso que se quiere para las variables de instancia y los métodos definidos en la clase:

  • public (public void CualquieraPuedeAcceder(){}): Cualquier clase desde cualquier lugar puede acceder a las variables y métodos de instacia públicos.
  • protected (protected void SoloSubClases(){}): Sólo las subclases de la clase y nadie más puede acceder a las variables y métodos de instancia protegidos.
  • private (private String NumeroDelCarnetDeIdentidad;) Las variables y métodos de instancia privados sólo pueden ser accedidos desde dentro de la clase. No son accesibles desde las subclases.
  • friendly (sin declaración específica, void MetodoDeMiPaquete(){}) Por defecto, si no se especifica el control de acceso, las variables y métodos de instancia se declaran friendly (amigas), lo que significa que son accesibles por todos los objetos dentro del mismo paquete, pero no por los externos al paquete. Es lo mismo que protected.

Comentarios en Java

11 de Junio de 2008

En Java hay tres tipos de comentarios:

// comentarios para una sola línea
 
/* comentarios de una o
más líneas
*/
 
/** comentario de documentación, de una o más líneas
*/

Los dos primeros tipos de comentarios son los que todo programador conoce y se utilizan del mismo modo. Los comentarios de documentación, colocados inmediatamente antes de una declaración (de variable o función), indican que ese comentario ha de ser colocado en la documentación que se genera automáticamente cuando se utiliza la herramienta de Java, javadoc. Dichos comentarios sirven como descripción del elemento declarado permitiendo generar una documentación de nuestras clases escrita al mismo tiempo que se genera el código.

En este tipo de comentario para documentación, se permite la introducción de algunos tokens o palabras clave, que harán que la información que les sigue aparezca de forma diferente al resto en la documentación.

Tutorial. Características de Java

10 de Junio de 2008

Las características principales que nos ofrece Java respecto a cualquier otro lenguaje de programación, son:

Es SIMPLE :

Java ofrece toda la funcionalidad de un lenguaje potente, pero sin las características menos usadas y más confusas de éstos. C++ es un lenguaje que adolece de falta de seguridad, pero C y C++ son lenguajes más difundidos, por ello Java se diseñó para ser parecido a C++ y así facilitar un rápido y fácil aprendizaje.

Java elimina muchas de las características de otros lenguajes como C++, para mantener reducidas las especificaciones del lenguaje y añadir características muy útiles como el garbage collector (reciclador de memoria dinámica). No es necesario preocuparse de liberar memoria, el reciclador se encarga de ello y como es un thread de baja prioridad, cuando entra en acción, permite liberar bloques de memoria muy grandes, lo que reduce la fragmentación de la memoria.

Java reduce en un 50% los errores más comunes de programación con lenguajes como C y C++ al eliminar muchas de las características de éstos, entre las que destacan:

  • aritmética de punteros
  • no existen referencias
  • registros (struct)
  • definición de tipos (typedef)
  • macros (#define)
  • necesidad de liberar memoria (free)

Es ORIENTADO 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, herencia y polimorfismo. Las plantillas de objetos son llamadas, 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 Objective C, propietario del sistema operativo Next. 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. Este inconveniente es resuelto por Java mediante una interfaz específica llamada RTTI ( RunTime 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.

Es DISTRIBUIDO :

Java se ha construido con extensas capacidades de interconexión TCP/IP. Existen librerías de rutinas para acceder e interactuar con protocolos como http y ftp . Esto permite a los programadores acceder a la información a través de la red con tanta facilidad como a los ficheros locales.

La verdad es que Java en sí no es distribuido, sino que proporciona las librerías y herramientas para que los programas puedan ser distribuidos, es decir, que se corran en varias máquinas, interactuando.

Es ROBUSTO :

Java realiza verificaciones en busca de problemas tanto en tiempo de compilación como en tiempo de ejecución. La comprobación de tipos en Java ayuda a detectar errores, lo antes posible, en el ciclo de desarrollo. Java obliga a la declaración explícita de métodos, reduciendo así las posibilidades de error. Maneja la memoria para eliminar las preocupaciones por parte del programador de la liberación o corrupción de memoria. También implementa los arrays auténticos , en vez de listas enlazadas de punteros, con comprobación de límites, para evitar la posibilidad de sobreescribir o corromper memoria resultado de punteros que señalan a zonas equivocadas. Estas características reducen drásticamente el tiempo de desarrollo de aplicaciones en Java.

Además, para asegurar el funcionamiento de la aplicación, realiza una verificación de los byte-codes , que son el resultado de la compilación de un programa Java. Es un código de máquina virtual que es interpretado por el intérprete Java. No es el código máquina directamente entendible por el hardware, pero ya ha pasado todas las fases del compilador: análisis de instrucciones, orden de operadores, etc., y ya tiene generada la pila de ejecución de órdenes.

Java proporciona, pues:

  • Comprobación de punteros
  • Comprobación de límites de arrays
  • Excepciones
  • Verificación de byte-codes

Es de ARQUITECTURA NEUTRAL :

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 ( run-time ) puede ejecutar ese código objeto, sin importar en modo alguno la máquina en que ha sido generado. Actualmente existen sistemas run-time para Solaris, SunOs, Windows, Windows NT, Linux, Irix, Aix, Mac, Apple y probablemente haya grupos de desarrollo trabajando en el portado a otras plataformas.

El código fuente Java se “compila” a un código de bytes de alto nivel independiente de la máquina. Este código (byte-codes) está diseñado para ejecutarse en una máquina hipotética que es implementada por un sistema run-time, que sí es dependiente de la máquina.

Es SEGURO :

La seguridad en Java tiene dos facetas. En el lenguaje, características como los punteros o el casting implícito que hacen los compiladores de C y C++ se eliminan para prevenir el acceso ilegal a la memoria. Cuando se usa Java para crear un navegador, se combinan las características del lenguaje con protecciones de sentido común aplicadas al propio navegador.

El lenguaje C, por ejemplo, tiene lagunas de seguridad importantes, como son los errores de alineación . Los programadores de C utilizan punteros en conjunción con operaciones aritméticas. Esto le permite al programador que un puntero referencie a un lugar conocido de la memoria y pueda sumar (o restar) algún valor, para referirse a otro lugar de la memoria. Si otros programadores conocen nuestras estructuras de datos pueden extraer información confidencial de nuestro sistema. Con un lenguaje como C, se pueden tomar números enteros aleatorios y convertirlos en punteros para luego acceder a la memoria:

printf( “Escribe un valor entero: ” );
scanf( “%u”,&puntero );
printf( “Cadena de memoria: %sn”,puntero );

Otra laguna de seguridad u otro tipo de ataque, es el Caballo de Troya . Se presenta un programa como una utilidad, resultando tener una funcionalidad destructiva. Por ejemplo, en UNIX se visualiza el contenido de un directorio con el comando ls . Si un programador deja un comando destructivo bajo esta referencia, se puede correr el riesgo de ejecutar código malicioso, aunque el comando siga haciendo la funcionalidad que se le supone, después de lanzar su carga destructiva. Por ejemplo, después de que el caballo de Troya haya enviado por correo el /etc/shadow a su creador, ejecuta la funcionalidad de ls persentando el contenido del directorio. Se notará un retardo, pero nada inusual.

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 byte-codes 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 byte-codes 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ámetros 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 punteros
  • El acceso a los campos de un objeto se sabe que es legal: public, private, protected
  • No hay ningún intento de violar las reglas de acceso y seguridad establecidas

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.

Las clases importadas de la red se almacenan en un espacio de nombres privado, asociado con el origen. Cuando una clase del espacio de nombres privado accede a otra clase, primero se busca en las clases predefinidas (del sistema local) y luego en el espacio de nombres de la clase que hace la referencia. Esto imposibilita que una clase suplante a una predefinida.

En resumen, las aplicaciones de Java resultan extremadamente seguras, ya que no acceden a zonas delicadas de memoria o de sistema, con lo cual evitan la interacción de ciertos virus. Java no posee una semántica específica para modificar la pila de programa, la memoria libre o utilizar objetos y métodos de un programa sin los privilegios del kernel del sistema operativo. Además, para evitar modificaciones por parte de los crackers de la red, implementa un método ultraseguro de autentificación por clave pública. El Cargador de Clases puede verificar una firma digital antes de realizar una instancia de un objeto. Por tanto, ningún objeto se crea y almacena en memoria, sin que se validen los privilegios de acceso. Es decir, la seguridad se integra en el momento de compilación, con el nivel de detalle y de privilegio que sea necesario.

Dada, pues la concepción del lenguaje y si todos los elementos se mantienen dentro del estándar marcado por Sun, no hay peligro. Java imposibilita, también, abrir ningún fichero de la máquina local (siempre que se realizan operaciones con archivos, éstas trabajan sobre el disco duro de la máquina de donde partió el applet), no permite ejecutar ninguna aplicación nativa de una plataforma e impide que se utilicen otros ordenadores como puente, es decir, nadie puede utilizar nuestra máquina para hacer peticiones o realizar operaciones con otra. Además, los intérpretes que incorporan los navegadores de la Web son aún más restrictivos. Bajo estas condiciones (y dentro de la filosofía de que el único ordenador seguro es el que está apagado, desenchufado, dentro de una cámara acorazada en un bunker y rodeado por mil soldados de los cuerpos especiales del ejército), se puede considerar que Java es un lenguaje seguro y que los applets están libres de virus.

Respecto a la seguridad del código fuente, no ya del lenguaje, JDK proporciona un desemsamblador de byte-code, que permite que cualquier programa pueda ser convertido a código fuente, lo que para el programador significa una vulnerabilidad total a su código. Utilizando javap no se obtiene el código fuente original, pero sí desmonta el programa mostrando el algoritmo que se utiliza, que es lo realmente interesante. La protección de los programadores ante esto es utilizar llamadas a programas nativos, externos (incluso en C o C++) de forma que no sea descompilable todo el código; aunque así se pierda portabilidad. Esta es otra de las cuestiones que Java tiene pendientes.

Es PORTABLE :

Más allá de la portabilidad básica por ser de arquitectura independiente, Java implementa otros estándares de portabilidad para facilitar el desarrollo. Los enteros son siempre enteros y además, enteros de 32 bits en complemento a 2. Además, Java construye sus interfaces de usuario a través de un sistema abstracto de ventanas de forma que las ventanas puedan ser implantadas en entornos Unix, Pc o Mac.

Es INTERPRETADO :

El intérprete Java (sistema run-time) puede ejecutar directamente el código objeto. Enlazar (linkar) un programa, normalmente, consume menos recursos que compilarlo, por lo que los desarrolladores con Java pasarán más tiempo desarrollando y menos esperando por el ordenador.

Existe la idea inexacta de que Java es más lento en ejecución que otros lenguajes por ser interpretado, pero las continuas mejoras que Sun realiza en las máquinas virtuales y la arquitectura del sistema, hacen que esa idea preconcebida ya no sea cierta. Java puede ser comparado en términos de velocidad con otros lenguajes de alto nivel.

La verdad es que Java para conseguir ser un lenguaje independiente del sistema operativo y del procesador que incorpore la máquina utilizada, es tanto interpretado como compilado. Y esto no es ningún contrasentido, me explico, el código fuente escrito con cualquier editor se compila generando el byte-code. Este código intermedio es de muy bajo nivel, pero sin alcanzar las instrucciones máquina propias de cada plataforma y no tiene nada que ver con el p-code de Visual Basic. El byte-code corresponde al 80% de las instrucciones de la aplicación. Ese mismo código es el que se puede ejecutar sobre cualquier plataforma. Para ello hace falta el run-time, que sí es completamente dependiente de la máquina y del sistema operativo, que interpreta dinámicamente el byte-code y añade el 20% de instrucciones que faltaban para su ejecución. Con este sistema es fácil crear aplicaciones multiplataforma, pero para ejecutarlas es necesario que exista el run-time correspondiente al sistema operativo utilizado.

Es MULTITHREADED :

Al ser multithreaded (multihilo), Java permite muchas ejecuciones simultáneas en un programa. Los threads (a veces llamados, procesos ligeros), son básicamente pequeños procesos o piezas independientes de un gran proceso. Al estar los threads contruidos en el lenguaje, son más fáciles de usar y más robustos que sus homólogos en C o C++.

El beneficio de ser miltithreaded consiste en un mejor rendimiento interactivo y mejor comportamiento en tiempo real. Aunque el comportamiento en tiempo real está limitado a las capacidades del sistema operativo subyacente (Unix, Windows, etc.), aún supera a los entornos de flujo único de programa (single-threaded) tanto en facilidad de desarrollo como en rendimiento.

Cualquiera que haya utilizado la tecnología de navegación concurrente, sabe lo frustrante que puede ser esperar por una gran imagen que se está trayendo. En Java, las imágenes se pueden ir trayendo en un thread independiente, permitiendo que el usuario pueda acceder a la información en la página sin tener que esperar por el navegador.

Es DINAMICO :

Java se beneficia todo lo posible 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.

Tutorial. Origen de Java

4 de Junio de 2008

Sun Microsystems, líder en servidores para Internet, uno de cuyos lemas desde hace mucho tiempo es “the network is the computer” (lo que quiere dar a entender que el verdadero ordenador es la red en su conjunto y no cada máquina individual), es quien ha desarrollado el lenguaje Java, en un intento de resolver simultáneamente todos los problemas que se le plantean a los desarrolladores de software por la proliferación de arquitecturas incompatibles, tanto entre las diferentes máquinas como entre los diversos sistemas operativos y sistemas de ventanas que funcionaban sobre una misma máquina, añadiendo la dificultad de crear aplicaciones distribuidas en una red como Internet.

He podido leer más de cinco versiones distintas sobre el origen, concepción y desarrollo de Java, desde la que dice que este fue un proyecto que rebotó durante mucho tiempo por distintos departamentos de Sun sin que nadie le prestara ninguna atención, hasta que finalmente encontró su nicho de mercado en la aldea global que es Internet; hasta la más difundida, que justifica a Java como lenguaje de pequeños electrodomésticos.

Hace algunos años, 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.

El mercado inicialmente previsto para los programas de FirstPerson eran los equipos domésticos: microondas, tostadoras y, fundamentalmente, televisión interactiva. Este mercado, dada la falta de pericia de los usuarios para el manejo de estos dispositivos, requería unos interfaces mucho más cómodos e intuitivos que los sistemas de ventanas que proliferaban en el momento.

Otros requisitos importantes a tener en cuenta eran la fiabilidad del código y la facilidad de desarrollo. James Gosling, el miembro del equipo con más experiencia en lenguajes de programación, decidió que las ventajas aportadas por la eficiencia de ‘C++ no compensaban el gran coste de pruebas y depuración. Gosling había estado trabajando en su tiempo libre en un lenguaje de programación que él había llamado Oak, el cual, aún partiendo de la sintaxis de C++, intentaba remediar las deficiencias que iba observando.

Los lenguajes al uso, como C o C++, deben ser compilados para un chip, y si se cambia el chip, todo el software debe compilarse de nuevo. Esto encarece mucho los desarrollos y el problema es especialmente acusado en el campo de la electrónica de consumo. La aparición de un chip más barato y, generalmente, más eficiente, conduce inmediatamente a los fabricantes a incluirlo en las nuevas series de sus cadenas de producción, por pequeña que sea la diferencia en precio ya que, multiplicada por la tirada masiva de los aparatos, supone un ahorro considerable. Por tanto, Gosling decidió mejorar las características de Oak y utilizarlo.

El primer proyecto en que se aplicó este lenguaje recibió el nombre de proyecto Green y consistía en un sistema de control completo de los aparatos electrónicos y el entorno de un hogar. Para ello 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 Duke, la actual mascota de Java. Posteriormente se aplicó a otro proyecto denominado VOD (Video On Demand) en el que se empleaba como interfaz para la televisión interactiva. Ninguno de estos proyectos se convirtió nunca en un sistema comercial, pero fueron desarrollados enteramente en un Java primitivo y fueron como su bautismo de fuego.

Una vez que en Sun se dieron cuenta de que a corto plazo la televisión interactiva no iba a ser un gran éxito, urgieron a FirstPerson a desarrollar con rapidez nuevas estrategias que produjeran beneficios. No lo consiguieron y FirstPerson cerró en la primavera de 1994.

Pese a lo que parecía ya un olvido definitivo, Bill Joy, cofundador de Sun y uno de los desarrolladores principales del Unix de Berkeley, juzgó que Internet podría llegar a ser el campo de juego adecuado para disputar a Microsoft su primacía casi absoluta en el terreno del software, y vio en Oak el instrumento idóneo para llevar a cabo estos planes. Tras un cambio de nombre y modificaciones de diseño, el lenguaje Java fue presentado en sociedad en agosto de 1995.

Lo mejor será hacer caso omiso de las historias que pretenden dar carta de naturaleza a la clarividencia industrial de sus protagonistas; porque la cuestión es si independientemente de su origen y entorno comercial, Java ofrece soluciones a nuestras expectativas. Porque tampoco vamos a desechar la penicilina aunque haya sido su origen fruto de la casualidad.