El lenguaje de programación Java  

Posted by Danny in

3. EL LENGUAJE DE PROGRAMACIÓN JAVA

Debido a que el presente documento centra su atención en la programación de dispositivos móviles, solamente se dará un descripción general del funcionamiento y características del lenguaje Java, ya que después se profundizará en su variante J2ME.

Cuando se programa en Java, se coloca todo el código en métodos, de la misma forma que se escriben funciones en lenguajes como C. En el presente capítulo se describen algunas de las principales características del lenguaje de programación Java.

3.1. Acerca de la máquina virtual

Como ya se ha mencionado, Java es un lenguaje interpretado, esto es que los programas no se compilan a archivos ejecutables, sino a archivos que habrán de ser interpretados por otros que si lo sean. Los archivos compilados de Java se llaman archivos de códigos de bytes o bytecodes.

Cuando se hace un programa en Java, el o los archivos que contengan el código fuente deben ser nombrados con extensión ".java" y al momento de ser compilados se creará un archivo de bytecodes con extensión ".class" del mismo nombre que el archivo fuente. Este archivo será la aplicación y, por lo tanto el que se habrá de ejecutar.

El trabajo de la máquina virtual es interpretar estos códigos de bytes según el sistema operativo en que se esté trabajando. He aquí el secreto de la portabilidad de Java: existe una máquina virtual para cada sistema operativo y los bytecodes se verifican cada vez que han de ser ejecutados, es decir, no corren directamente sobre el sistema operativo, sino que la maquina virtual los ejecuta convirtiendo los bytecodes a instrucciones propias de la plataforma anfitrión.

3.2.Características básicas del lenguaje

3.2.1. Comentarios

Los comentarios se introducen en los programas como ayuda para quienes habrán de leerlos, ya sea los propios programadores o aquellos quienes les han de dar mantenimiento. Un comentario no se ejecuta ni compila junto con el resto del programa, es únicamente para información. En Java hay tres tipos de comentarios:

A) // comentarios para una sola línea.

Todo el texto de una línea que se encuentre después de "//" será omitido por el compilador.

B) /* comentarios de una o

más líneas*/

Se omitirá en la compilación y ejecución todo el texto contenido a partir de la apertura del comentario "/*" y hasta su cierre "*/".

C) /** comentario de documentación,

de una o más líneas*/

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 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.

3.2.2. Identificadores

Los identificadores se utilizan para nombrar variables, funciones, clases y objetos; cualquier cosa que el programador necesite identificar o usar.

En Java, un identificador debe comenzar con una letra, un subrayado (_) o un símbolo de dólar ($). Los siguientes caracteres pueden ser letras o dígitos. Se distinguen las mayúsculas de las minúsculas (case sensitive) y no hay longitud máxima en el identificador.

Serían identificadores válidos:

identificador

nombre_usuario

Nombre_Usuario

_variable_del_sistema

$transaccion

Y su uso sería, por ejemplo:

int contador_principal;

char _lista_de_archivos;

float $cantidad_en_Ptas;

3.2.3. Palabras clave

Las palabras claves en un lenguaje de programación son aquellas que tienen alguna función especifica para dicho lenguaje, por ejemplo una palabra que indique la impresión de una cadena de texto en pantalla.

Las siguientes son las palabras clave que están definidas en Java y que no se pueden utilizar como identificadores:

abstract continue for new switch

boolean default goto null synchronized

break do if package this

byte double implements private threadsafe

byvalue else import protected throw

case extends instanceof public transient

catch false int return true

char final interface short try

class finally long static void

const float native super while

Seguramente no serán estas las únicas palabras que no podrán ser utilizadas como identificadores, debido a que existen también las palabras utilizadas por las clases que utilicemos (extendamos) en nuestros programas y las palabras reservadas de Java.

3.2.4. Palabras Reservadas

Además de las anteriores, el lenguaje se reserva unas cuantas palabras más, pero que hasta ahora no tienen un cometido específico. Esas palabras son:

cast future generic inner

operator outer rest var

3.2.5. Literales y tipos de datos

Java utiliza cinco tipos de datos básicos:

A) Enteros. Números sin punto decimal.

byte 8 bits complemento a dos

short 16 bits complemento a dos

int 32 bits complemento a dos

long 64 bits complemento a dos

Por ejemplo: 21, 077, 0xDC00

B) Reales en coma flotante. Números con punto decimal.

float 32 bits IEEE 754

double 64 bits IEEE 754

Por ejemplo: 3.14, 2e12, 3.1E12

C) Lógicos o booleanos. almacenan sólo valores de falso o verdadero.

true (verdadero).

false (falso).

D) Caracteres. Únicamente almacenan un carácter, una letra, símbolo o número (no se toma en cuenta su valor matemático).

Por ejemplo: "a", \t, \u???? [????] es un número unicode.

E) Cadenas. Son una agrupación de caracteres.

Por ejemplo: "Esto es una cadena literal"

3.2.5.1.Arreglos

Son asociaciones de varios datos del mismo tipo, por ejemplo un arreglo de cinco datos enteros o una lista de diez nombres, también son llamados arrays.

En Java se pueden declarar arreglos de cualquier tipo:

char s[];

int iArray[];

Incluso se pueden construir arreglos de arreglos:

int tabla[][] = new int[4][5];

Los límites de los arreglos se comprueban en tiempo de ejecución para evitar desbordamientos y la corrupción de memoria, es decir, se verifica que no se intenten ocupar más espacios de los especificados en la declaración del arreglo.

En Java un arreglo es realmente un objeto, porque tiene definido el operador "[ ]". Tiene una función miembro: length. Se puede utilizar este método para conocer su longitud.

int a[][] = new int[10][3];

a.length; /* 10 */

a[0].length; /* 3 */

Para crear un arreglo en Java hay dos métodos básicos. Crearlo vacío:

int lista[] = new int[50];

o se puede crear el arreglo con sus valores iniciales:

String nombres[] = {

"Juan","Pepe","Pedro","María"

};

Esto que es equivalente a:

String nombres[];

nombres = new String[4];

nombres[0] = new String( "Juan" );

nombres[1] = new String( "Pepe" );

nombres[2] = new String( "Pedro" );

nombres[3] = new String( "María" );

No se pueden crear arreglos estáticos en tiempo de compilación:

int lista[50]; // generará un error en tiempo de compilación

Tampoco se puede llenar un array sin declarar el tamaño con el operador new:

int lista[];

for( int i=0; i <>

lista[i] = i;

Es decir, todos los arrays en Java son estáticos, esto mejora la seguridad en el manejo de memoria. Para convertir un arreglo en el equivalente a los arreglos dinámicos de C++, se usa la clase vector, que permite operaciones de inserción, borrado, etc.

3.2.6. Operadores

Los operadores de Java son muy parecidos en estilo y funcionamiento a los de C. En la siguiente tabla aparecen los operadores que se utilizan en Java, por orden de precedencia:

. [] () ++ -- !

~ instanceof * / % +

- << >> >>> < >

<= >= == != & ^

| && || ? : = op=

*= /= %= += -=

Los operadores numéricos se comportan como esperamos:

int + int = int

Los operadores relacionales devuelven un valor booleano.

Para las cadenas, se pueden utilizar los operadores relacionales para comparaciones además de + y += para la concatenación:

String nombre = "nombre" + "Apellido";

El operador = siempre hace copias de objetos, marcando los antiguos para borrarlos, y ya se encargará el garbage collector de devolver al sistema la memoria ocupada por el objeto eliminado.

3.2.7. Separadores

Los separadores en Java definen la forma y función del código. Agrupan bloques de código e identificadores, definen la prioridad en operaciones. Los separadores admitidos en Java son los siguientes:

-() - paréntesis. Para contener listas de parámetros en la definición y llamada a métodos. También se utiliza para definir precedencia en expresiones.

-{} - llaves. Para contener los valores de matrices iniciadas automáticamente. También se utiliza para definir un bloque de código, para clases, métodos y ámbitos locales.

-[] - corchetes. Para declarar tipos matriz. También se utiliza cuando se referencian valores de matriz.

-; - punto y coma. Separa sentencias.

-, - coma. Separa identificadores consecutivos en una declaración de variables. También se utiliza para encadenar sentencias dentro de una sentencia for.

-. - punto. Para separar nombres de paquete de subpaquetes y clases. También se utiliza para separar una variable o método de una variable de referencia.

3.2.8. Control de flujo

Las instrucciones de control de flujo son aquellas que, basándose en criterios dados por el programador, alteran el flujo natural (lineal) del programa.

En Java tenemos casi las mismas instrucciones de control de flujo (selección, decisión, salto y repetición) que en C.

3.2.8.1.Estructuras de decisión y selección

Son fragmentos de código que se ejecutan solamente si una condición contenida en ellos se cumple, como se muestra en los siguientes ejemplos:

A) if/else:

if( condición_Boolean ) {

Instrucciones_si_se_cumple_la_condición_Boolean;

}

else {

Instrucciones_si:no_se_cumple;

}

B) switch:

switch( expr1 ) {

case expr2:

instrucciones_si_expr1_=_expr2;

break;

case expr3:

instrucciones_si_expr1_=_expr3;

break;

default:

instrucciones_si_expr1_<>_expr2_y_a_expr3;

break;

}

3.2.8.2.Ciclos de repetición

Estas estructuras repiten su ejecución tantas veces como se haya indicado o bien cuando se cumpla una determinada condición.

A) for

for( expr1 inicio; expr2 test; expr3 incremento ) {

sentencias;

}

También se soporta el operador coma (,) en los ciclos for

for( a=0,b=0; a <>

B) while

while( Boolean ) {

sentencias;

}

C) do/while

do {

sentencias;

}while( Boolean );

3.2.8.3.Excepciones

Algunas veces los programas producen algún error en tiempo de ejecución y quisiéramos tener la capacidad de decirle qué hacer cuando esto suceda, principalmente para evitar que el programa se colapse cada vez que el error se presenta. para esto nos sirven las excepciones de Java.

A) try-catch-throw

try {

sentencias;

} catch( Exception ) {

sentencias;

}

Java implementa excepciones para facilitar la construcción de código robusto. Cuando ocurre un error en un programa, el código que encuentra el error lanza una excepción, que se puede capturar y recuperarse de ella. Java proporciona muchas excepciones predefinidas.

3.2.8.4.Control general del flujo

Rompen el flujo natural del programa incondicionalmente, ya sea para terminar un módulo o todo el programa o simplemente para pasar a otro lugar del código.

break [etiqueta]

continue [etiqueta]

return expr;

etiqueta: sentencia;

Por ejemplo, en caso de que nos encontremos con ciclos anidados, se permite el uso de etiquetas para poder salirse de ellos, por ejemplo:

uno: for( ) {

dos: for( ) {

continue; /* seguiría en el ciclo interno, pero omitiría las instrucciones siguientes*/

continue uno; // seguiría en el ciclo uno principal

break uno; // se saldría del ciclo principal

}

}

En el código de una función siempre hay que ser consecuentes con la declaración que se haya hecho de ella. Por ejemplo, si se declara una función para que devuelva un entero, es imprescindible que se coloque un return final para salir de esa función, independientemente de que haya otros en medio del código que también provoquen la salida de la función. En caso de no hacerlo se generará un a advertencia (Warning), y el código Java no se puede compilar con "Warnings".

int func() {

if( a == 0 )

return 1;

return 0; // es imprescindible porque se retorna un entero

}

3.2.9. Clases

Las clases son la parte fundamental de Java. Todo en Java forma parte de una clase, es una clase o describe como funciona una clase. por lo tanto, 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, todo debe pertenecer a una clase. 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. En C la unidad fundamental son los archivos con código fuente, en Java son las clases. De hecho son pocas las sentencias que se pueden colocar fuera del bloque de una clase. La palabra clave import (equivalente al #include) puede colocarse al principio de un archivo, fuera del bloque de la clase. Sin embargo, el compilador reemplazará esa sentencia con el contenido del archivo que se indique, que consistirá, como es de suponer, en más clases.

3.2.9.1.Tipos de clases

Hasta ahora sólo se ha utilizado la palabra clave public para calificar el nombre de las clases que se han visto, pero hay más modificadores. Los tipos de clases que se pueden 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 hilos (threads) de programación; el sistema se encarga de colocar las banderas (flags) necesarias para evitarlo. Este mecanismo hace que desde hilos diferentes se puedan modificar las mismas variables sin que haya problemas de que se sobrescriban.

-protected.

Una clase definida como protected puede ser utilizadas desde cualquier clase del mismo paquete, sin posibilidad, a diferencia de las clases public, de ser accedidas desde otros paquetes, aun importandolas.

3.2.9.2.Paquetes de clases

Al crear una clase se puede incluir en un paquete que se compilará como tal, es decir, la aplicación no funcionará si falta alguna de las clases integrantes del paquete.

La agrupación en paquetes es bastante útil para motivos de organización y portabilidad, ya que nos obliga a tener todas las clases relacionadas a un proyecto en la misma carpeta o directorio. Para incluir una clase en un paquete se hace de la siguiente forma:

package Clases; //esta línea indica que esta clase forma parte del paquete //clases

public MiClase {

int i; ....

3.2.10. Variables y métodos de instancia

Una clase en Java puede contener variables y métodos. Las variables pueden ser tipos primitivos como int, char, etc. Los métodos son funciones.

Por ejemplo, en el siguiente segmento de código podemos observarlo:

public MiClase {

int i;

public MiClase() {

i = 10;

}

public void Suma_a_i( int j ) {

i = i + j;

}

}

La clase MiClase contiene una variable (i) y dos métodos, MiClase que es el constructor de la clase y Suma_a_i( int j ).

3.2.10.1.Ámbito de una variable

Los bloques de sentencias compuestas en Java se delimitan con dos llaves. Las variables de Java sólo son válidas desde el punto donde están declaradas hasta el final de la sentencia compuesta que la engloba. Se pueden anidar estas sentencias compuestas, y cada una puede contener su propio conjunto de declaraciones de variables locales. Sin embargo, no se puede declarar una variable con el mismo nombre que una de ámbito exterior.

El siguiente ejemplo intenta declarar dos variables separadas con el mismo nombre. En C y C++ son distintas, porque están declaradas dentro de ámbitos diferentes. En Java, esto es ilegal.

Class ambito {

int i = 1; // ámbito exterior

{ // crea un nuevo ámbito

int i = 2; // error de compilación

}

}

3.2.10.2.Métodos y Constructores

Los métodos son funciones que pueden ser llamadas dentro de la clase o por otras clases. El constructor es un tipo específico de método que siempre tiene el mismo nombre que la clase.

Cuando se declara una clase en Java, se pueden declarar uno o más constructores opcionales que realizan la inicialización cuando se instancia (se crea) un objeto de dicha clase.

Utilizando el código de ejemplo anterior, cuando se crea una nueva instancia de MiClase, se crean (instancian) todos los métodos y variables, y se llama al constructor de la clase:

MiClase mc;

mc = new MiClase();

La palabra clave new se usa para crear una instancia de la clase. Antes de ser instanciada con new no consume memoria, simplemente es una declaración de tipo. Después de ser instanciado un nuevo objeto mc, el valor de i en el objeto mc será igual a 10. Se puede referenciar la variable (de instancia) i con el nombre del objeto:

mc.i++; // incrementa la instancia de i de mc

Al tener mc todas las variables y métodos de MiClase, se puede usar la primera sintaxis para llamar al método Suma_a_i() utilizando el nuevo nombre de clase mc:

mc.Suma_a_i( 10 );

y ahora la variable mc.i vale 21.

3.2.10.3.Finalizadores

Java no utiliza destructores (al contrario que C++) ya que tiene una forma de recoger automáticamente todos los objetos que se salen del alcance. No obstante proporciona un método que, cuando se especifique en el código de la clase, el reciclador de memoria (garbage collector) llamará:

// Cierra el canal cuando este objeto es reciclado

protected void finalize() {

close();

}

3.3. Programación multihilo (multithread)

Se le llama programación multihilo o multithreaded (en inglés) al método de programación donde el flujo del programa se diseña como caminos o hilos independientes que pueden ejecutarse al mismo tiempo,

Lo anterior significa que con Java se pueden realizar aplicaciones que realicen varias tareas a la vez y que se puede controlar cada una de estas tareas independientemente del resto.

La programación multihilo en Java se logra realizando una agrupación en hilos como si de procedimientos se tratase, aunque se usa la clase thread.

En el siguiente ejemplo veremos como crear un hilo en lenguaje Java y como ordenar su ejecución:

//La clase principal

public class MiClase{

//código de la clase

//Se deben instanciar las clases hilo.

Hilo1 H1;

Hilo2 H2;

H1 = new Hilo1 ("1");

H2 = new Hilo2 ();

//Llamadas a los hilos

H1.start

H2.start

}

//Hilos

class Hilo1 extends Thread { //Extiende (hereda) la clase Thread

//Constructor de la clase Hilo1

public Hilo1(String nom){ //este constructor utiliza un nombre de hilo

}

pulic void run(){

//run contiene el código que se ejecutará

}

}

class Hilo2 extends Thread {

public Hilo2(){ /*Variante del constructor que no pide nombre de hilo (define los nombres de hilo como Thread1, Thread2... Treadn.*/

}

pulic void run(){

}

}

"Un programa inicia la ejecución de un hilo invocando el método start de ese hilo, a su vez start, invoca el método run. Una vez que start echa a andar el hilo, regresa de inmediato el control a su invocador. De ahí en adelante el invocador se ejecutará en paralelo con el hilo iniciado. El método start lanza una excepción de estado de hilo ilegal (IllegalThreadStateException) si el hilo que está tratando de iniciar ya se está ejecutando."[1]

Desafortunadamente nuestro espacio para la explicación del lenguaje Java es reducido puesto que no es ese nuestro tema principal, aunque se incluye por considerarse necesario, y no podemos dedicarle lo merecido al interesante tema de la programación multihilo. Recomendamos al lector el libro citado al pie de esta página, dedica un capítulo (que tal vez resulte también insuficiente pero es mejor que dos cuartillas) completo a este tema.


Entradas relacionadas:

0 comentarios

Publicar un comentario