Vous êtes sur la page 1sur 87

FASES PARA LA ELABORACIN DE UN PROGRAMA

INFORMTICO
El desarrollo de un programa o de un conjunto de aplicaciones se basa en un concepto
llamado ciclo de vida. Son una serie de etapas o fases que hay que seguir
secuencialmente.
Las fases o etapas son:

Anlisis.
Diseo.
Codificacin o construccin.
Implantacin o explotacin.
Mantenimiento.

Paso a explicar las fases:

ANLISIS
En esta fase se establece el producto a desarrollar, siendo necesario especificar los
procesos y estructuras de datos que se van a emplear. Debe existir una gran
comunicacin entre el usuario y el analista para poder conocer todas las necesidades que
precisa la aplicacin. En el caso de falta de informacin por parte del usuario se puede
recurrir al desarrollo de prototipos para saber con ms precisin sus requerimientos.
En el anlisis estructurado se pueden emplear varias tcnicas como:
Diagramas de flujo de datos: Sirven para conocer el comportamiento del sistema
mediante representaciones grficas.
Modelos de datos: Sirven para conocer las estructuras de datos y sus caractersticas.
(Entidad relacin y formas normales)
Diccionario de datos: Sirven para describir todos los objetos utilizados en los grficos,
as como las estructuras de datos.
Definicin de los interfaces de usuario: Sirven para determinar la informacin de
entrada y salida de datos.
Al final de esta fase tenemos que tener claro las especificaciones de la aplicacin.

DISEO
En esta fase se alcanza con mayor precisin una solucin ptima de la aplicacin,
teniendo en cuenta los recursos fsicos del sistema (tipo de ordenador, perifricos,
comunicaciones, etc) y los recursos lgicos. (sistema operativo., programas de utilidad,
bases de datos, etc)
En el diseo estructurado se pueden definir estas etapas:
Diseo externo: Se especifican los formatos de informacin de entrada y salida.
(pantalla y listados)
Diseo de datos: Establece las estructuras de datos de acuerdo con su soporte fsico y
lgico. (estructuras en memoria, ficheros y hojas de datos)
Diseo modular: Es una tcnica de representacin en la que se refleja de forma
descendente la divisin de la aplicacin en mdulos. Est basado en diagramas de flujo
de datos obtenidos en el anlisis.
Diseo procedimental: Establece las especificaciones para cada mdulo, escribiendo el
algoritmo necesario que permita posteriormente una rpida codificacin. Se emplean
tcnicas de programacin estructurada, normalmente ordinogramas y pseudocdigo.
Al final de esta etapa se obtiene el denominado cuaderno de carga.

CODIFICACIN

Consiste en traducir los resultados obtenidos a un determinado lenguaje de


programacin, teniendo en cuenta las especificaciones obtenidas en el cuaderno de
carga. Se deben de realizar las pruebas necesarias para comprobar la calidad y
estabilidad del programa.
Las pruebas se pueden clasificar en:
Pruebas unitarias: Sirven para comprobar que cada mdulo realice bien su tarea.
Pruebas de interconexin: Sirven para comprobar en el programa el buen
funcionamiento en conjunto de todos sus mdulos.
Pruebas de integracin: Sirven para comprobar el funcionamiento correcto del
conjunto de programas que forman la aplicacin. (el funcionamiento de todo el sistema)

EXPLOTACIN
En esta fase se realiza la implantacin de la aplicacin en el sistema o sistemas fsicos
donde van a funcionar habitualmente y su puesta en marcha para comprobar el buen
funcionamiento.
Actividades a tener en cuenta o realizar:

Instalacin del/los programa/s.


Pruebas de aceptacin al nuevo sistema.
Conversin de la informacin del antiguo sistema al nuevo (si hay una aplicacin
antigua)
Eliminacin del sistema anterior.

Al final de esta fase se debe de completar la informacin al usuario respecto al nuevo


sistema y su uso. As como facilitarle toda la documentacin necesaria para una correcta
explotacin del sistema (manual de ayuda, manual de uso, gua de la aplicacin, etc.)

MANTENIMIENTO
Esta es la fase que completa el ciclo de vida y en ella nos encargaremos de solventar los
posibles errores o deficiencias de la aplicacin. Existe la posibilidad de que ciertas
aplicaciones necesiten reiniciar el ciclo de vida.
Tipos de mantenimiento:
Mantenimiento correctivo: Consiste en corregir errores no detectados en pruebas
anteriores y que aparezcan con el uso normal de la aplicacin. Este mantenimiento puede
estar incluido en la garanta o mantenimiento de la aplicacin.
Mantenimiento adaptativo: Consiste en modificar el programa a causa de cambio de
entorno grfico y lgico en el que estn implantados. (nuevas generaciones de
ordenadores, nuevas versiones del sistema operativo, etc.)
Mantenimiento perfectivo: Consiste en una mejora sustancial de la aplicacin al recibir
por parte de los usuarios propuestas sobre nuevas posibilidades y modificaciones de las
existentes.
Los tipos de mantenimiento adaptativo y perfectivo reinician el ciclo de vida, debiendo
proceder de nuevo al desarrollo de cada una de sus fases para obtener un nuevo
producto.

INSTALANDO NETBEANS
HOLA MUNDO:

IDE

CREANDO

EL

No tiene mucha dificultad instalar el ambiente de desarrollo, simplemente ejecutan el instalador y


siguen los pasos. Igualmente, para evitar problemas lo veremos paso a paso. Inicialmente tenemos
esta ventana:

Luego de que cargue nos aparece esta:

All vern qu es lo van a instalar. En este caso se lista todo lo que vimos hoy porque yo
baj el paquete completo. Si le dan en Personalizar podrn elegir qu instalar y qu no.
Damos en Siguiente:

Nos aparece el hermoso contrato de licencia que todos morimos por leer detenidamente
sin perdernos una sola palabra. No creo que exista alguien en el ancho mundo que solo
de clic en Acepto los trminos del acuerdo de licencia y de Siguiente si leer
absolutamente nada o s? ;)
Dependiendo de los componentes elegidos para instalar podran aparecer ms hermosos
contratos as que estaremos felices de tener tanto que leer.
Llegamos a esta ventana:

Aqu tienen dos cuadros, uno para elegir donde instalar NetBeanas (les recomiendo que
dejen el que viene por defecto) y otro para indicarle a NetBeans donde encontrar el JDK.

En mi caso aparece ya por defecto porque la variable PATH est bien configurada, sin
embargo, si no les aparece le dan clic en Examinar y buscan ustedes a mano el lugar
donde esta su JDK y listo, NetBeans lo detecta y no nos hace problema. Damos clic en
Siguiente. Dependiendo de las opciones elegidas para instalar podra aparecernos
alguna otra ventana para elegir donde instalar los otros componentes.

Se nos muestra un resumen de lo que instalaremos. La imagen de ustedes puede diferir


en funcin de lo que hayan seleccionado para instalar. Si todo est bien le dan clic a
Instalar y esperan pacientemente que se cargue todo. Si instalan el paquete completo
realmente puede demorar, no importa que tan potente sea su equipo. No desesperen, la
instalacin configura muchas cosas, de modo que djenla terminar tranquilamente.
Les recomiendo que vayan creando una carpeta donde colocar sus proyectos Java. Con
este IDE no tienen problemas de rutas ni de nombres de directorios. Es moderno as que
pueden tener espacios y dems, ahora s, bienvenidos al siglo 21 jejeje.
-------------------------------------------------------------------------------------

El clsico Hola Mundo:


Como era de esperarse haremos nuestro
Hola Mundo en Java. Ya deben saber que la
funcin de crear un programa tan tonto es
chocar contra el lenguaje nuevo y contra el
ambiente de desarrollo, as que vamos a
ello. Al abrir el IDE nos aparece la ventana
de carga:

Luego visualizamos la interfaz grfica de NetBeans con la Pgina de Inicio:

Les recomiendo que toqueteen esta pgina y exploren, hay varias cosas interesantes. Si
no quieren verla ms cada vez que abren el IDE desmarquen la opcin Mostrar al Inicio.
Bien, creemos nuestro primer proyecto. Al igual que en Modula, Java funciona con
proyectos, as que vamos a Archivo --> Proyecto Nuevo:

Debemos elegir dos cosas: Categora y Proyecto. Las categoras disponibles dependern
de lo que hayan instalado. Lo que a m me interesa ahora es Java Estndar as que
elegimos categora Java y luego Java Application.
Las Java Application son aplicaciones Java comunes, es decir, programas de escritorio.
Damos en Siguiente:

Debemos darle un nombre al proyecto. En mi caso escribo HolaMundo (no debe


contener espacios). Luego elegimos la ubicacin. NetBeans crea una ubicacin por
defecto que si les gusta pueden dejarla. Dentro de dicha ubicacin crea automticamente
una carpeta con el nombre del proyecto para guardar todos sus archivos.
Por defecto est marcada la opcin Crear clase principal. Por ahora desmrquenla. Den
clic
en
Terminar.
Tras eso NetBeans crea el proyecto y nos muestra esta ventana:

A la izquierda tenemos un panel con tres pestaas:

Proyectos: NetBeans nos muestra todos los proyectos que tenemos creados,
como ahora solo tenemos uno es el nico que podemos visualizar de momento. Ya
tendremos ms.
Archivos: Nos permite visualizar todos los archivos que componen a nuestro
proyecto.
Prestaciones: Son herramientas que amplan un proyecto, como por ejemplo,
conexin a base de datos. De momento no lo usaremos.

Si en la pestaa Proyecto hacemos clic en el smbolo de ms (+) de un proyecto se nos


despliega mucho sobre el contenido del mismo. Aprenderemos a usar esto poco a poco.
En Modula tenamos mdulos que conformaban a nuestros programas, cada cual estaba
conformado (excepto el mdulo principal) por un archivo de definicin DEF y uno de
implementacin MOD; estos mdulos podran representar eventualmente a algn tipo de
objeto. En Java los mdulos sern llamados Clases. Por suerte no tendremos dos tipos de
archivos diferentes, sino que cada clase tendr un nico archivo. Al igual que en Modula
tenamos un mdulo principal, en Java tendremos una clase principal que ser la que
iniciar al programa.
De esta manera, lo que debemos hacer ahora es crear la clase principal de nuestro
programa. Tenemos dos formas de hacerlo:
Vamos al men Archivo --> Archivo Nuevo o bien presionamos el botn Archivo Nuevo
de la barra de herramientas (acceso rpido CTRL + N). Elegimos la categora Java y el
tipo de archivo Java Class (Clase Java). Damos clic en Siguiente y luego le damos un
nombre a la clase (no puede contener espacios). No importa el nombre que le demos. Yo
le puse HolaMundo a la ma pero por costumbre. Damos clic en Terminar y tendremos
algo como esto:

Como ven a la izquierda ahora podemos ver la nueva clase (archivo .java) agregada al
proyecto. A la derecha vemos una pestaa con el nombre de la clase y la opcin Source
(fuente) marcada. NetBeans ya nos genera algo de cdigo fuente en la clase. Lo que est
en gris son comentarios (ya hablaremos de ellos luego porque Java tiene tres tipos de
comentarios y aqu ya tenemos dos).
Borren los comentarios.
La otra forma es hacer clic derecho sobre el cono del proyecto (la tazita de caf roja),
eligen Nuevo --> Java Class. Los dems pasos son iguales que para la manera anterior.
Veamos el cdigo fuente que tenemos:
Cdigo:

public class HolaMundo {


}

Para empezar NetBeans pinta en azul las palabras reservadas del lenguaje. All tenemos:

public: Indica que lo que va a ser declarado luego es de acceso pblico. Lo

veremos ms adelante, por ahora simplemente saben que tiene que ir.
class: Indica que lo que estamos declarando es una clase. En Modula usabamos la
palabra MODULE. Las clases siempre se declaran con esta palabra.

Luego de la palabra class va el nombre de la clase, al igual que en Modula luego de la


palabra MODULE iba el nombre del mdulo. El nombre de la clase es un identificador y
por tanto cumple las mismas condiciones que los identificadores de Pascal y Modula
excepto porque estos s pueden llevar tildes (acentos) y la letra . Ahora ya no
tendremos que escribir el identificador AO como ANIO.

En Pascal el programa estaba escrito dentro de los bloques BEGIN y END y en Modula el
mdulo principal llevaba el bloque BEGIN/END. En Java nos olvidamos de las palabras
BEGIN y END y las sustituimos por las llaves { y } respectivamente. De este modo, en el
ejemplo, la llave { indica el inicio de la clase y la llave } indica el final de la misma. Lo
que tenemos entonces all ahora es una clase pblica que se llama HolaMundo y est
vaca
porque
no
tiene
cdigo
ninguno
dentro
de
las
llaves.
Escriban a mano entonces dentro de las llaves este cdigo:
Cdigo:

public static void main(String[] args){


}

Como vern NetBeans va corrigiendo sintaxis en tiempo real. Adems, cuando escribimos
la llave { y damos enter, NetBeans nos agrega la llave de cierre } ya indentada y todo.
Otra cosa til es que si nos paramos en una llave de apertura el IDE nos pinta en amarillo
cul es la que la cierra y viceversa. Lo mismo con los parntesis y todo tipo de smbolo de
apertura y cierre.
Qu es eso que acabamos de escribir? De momento les digo que es un procedimiento
que se llama main (principal en ingls). Todo programa Java tiene una sola clase principal
(al igual que los programas en Modula tenan un solo mdulo principal). La clase principal
es la nica que tiene el procedimiento main que acabamos de escribir. Justamente eso es
lo que la marca como clase principal. De momento no me detendr a explicar mucho ms
de este procedimiento, asuman que es as y a medida que avancemos todo se ir viendo
claramente.
Algo importante es que el procedimiento tambin tiene llave de apertura y cierre. En
Pascal y Modula llevaban un bloque BEGIN/END.
Bien, dentro de este procedimiento escribiremos el cdigo:
Cdigo:

System.out.println("Hola Mundo");

Esto ltimo es una tpica sentencia de Java. Como ven termina en punto y coma (;). Al
igual que en Pascal y Modula, el smbolo de punto y coma tiene la funcin de separador,
es decir, es el que separa una sentencia (instruccin) de otra. Las llaves de cierre no
llevan punto y coma al final.
Antes de pasar al detalle de lo que significan estas palabras, veamos el cdigo completo:
Cdigo:

public class HolaMundo {


public static void main(String[] args){
System.out.println("Hola Mundo");
}
}

Ahora van al men Ejecutar --> Limpiar y generar Main Project. Luego van a
Ejecutar --> Ejecutar Main Project. El IDE les pedir que indiquen cul es la clase
principal del proyecto. Seleccionen la suya y den Aceptar.
Tendrn esta pantalla:

Vern que debajo apareci la pestaa Salida HolaMundo (run). Esa es la salida de la
consola del IDE, es decir, lo que antes vean en una pantalla negra con letras blancas
horribles, ahora lo ven en esta pantalla dentro del IDE. Como ven, apareci el mensaje
Hola Mundo.
Las opciones del men Ejecutar las tienen tambin en la barra de herramientas.
Noten tambin que ahora en la pestaa Proyectos apareci un cono verde de Play
(reproducir) en el cono de la clase que tenemos. Eso indica que ahora NetBeans la
reconoce como clase principal y que es desde ella que ejecutar el programa. Esto lo
veremos enseguida; primero analicemos un poquito ms lo que tenemos en nuestro
cdigo:

Una declaracin de clase:


Cdigo:

public class HolaMundo

Como ya dije, en Java los programas se organizan en clases y no en mdulos como


suceda en Modula 2. Las clases siempre se declaran con la palabra reservada
class y luego un identificador. As, la clase HolaMundo poda haber sido declarada
como
Cdigo:

class HolaMundo

El modificador de acceso public indica adems que la clase declarada es pblica.


Por ahora esto lo dejamos en el aire y simplemente nos limitamos a colocarlo.
Las clases tienen un bloque de cdigo fuente delimitado por la llave de apertura {
y la de cierre }.

Dentro del bloque de la clase HolaMundo tenemos un procedimiento llamado main


cuyo encabezado es
Cdigo:

public static void main(String[] args)

La declaracin de subprogramas (procedimientos y funciones) en Java la veremos


ms adelante. Por ahora sepan que esto es un procedimiento y nada ms. Lo
destacable de este procedimiento es que se llama main y solo puede haber un
procedimiento llamado main en todo el programa sin importar cuantas clases
existan, es decir, solo una clase puede tener el procedimiento main (tenemos
algunas excepciones pero las veremos luego). La clase que contiene a este
procedimiento es la clase principal del programa. Cuando ejecutamos nuestra
aplicacin la ejecucin comenzar por el procedimiento main.
NetBeans busca en todas las clases de nuestro programa para detectar cual es la
que contiene al procedimiento main y as designarla como clase principal (main
class). Por eso en un principio nos pregunt cul era la clase principal. Una vez
designada NetBeans no volver a preguntarnos, simplemente correr el programa
desde la clase designada como principal.
Una vez detectada solo damos clic en el botn Ejecutar Main Project de la barra de
herramientas y ya, nuestro programa correr tranquilamente.
Si han puesto atencin a lo que escribieron habrn visto que NetBeans ha puesto
en letra cursiva el identificador main. Ya debera estar claro que es por su
importancia
en
la
programacin
en
Java.
Un procedimiento como este declarado en Modula sera:
Cdigo:

PROCEDURE main(args: ARRAY OF TipoString);

Donde TipoString est declarado as:


Cdigo:

TYPE TipoString= ARRAY[1..N] OF CHAR;

Vern que el argumento es un arreglo de strings.

Dentro del bloque del procedimiento main tenemos:

Cdigo:

System.out.println("Hola Mundo");

En Java la salida estndar es System.out. En realidad System es una clase ya


creada en Java perteneciente al paquete java.lang (hablaremos de paquetes
mucho ms adelante). Esta clase tiene operaciones que nos permiten realizar tareas
con el sistema, como por ejemplo, mostrar texto en consola con out, que es una
variable. Todo esto ahora es super confuso y complejo. Lo importante es que
System.out representa la salida estndar en Java y que con esto tenemos los
procedimientos println y print tal como si fueran WriteLn y Write en Pascal
respectivamente.
El procedimiento println recibe datos como argumentos y los muestra en pantalla.
En este caso hemos pasado un literal (texto entre comillas), pero bien puede ser
una variable, un nmero, etc; tal como suceda con Write y WriteLn en Pascal
aunque aquellos podan recibir varios argumentos separados por comas, pero print
y println no.
Espero entonces que quede claro que print imprime los datos y deja el cursor justo
al final de la lnea en que imprimi y println deja el cursor una lnea ms abajo, es
decir,
imprime
un
fin
de
lnea
luego
de
los
datos.
Si se fijan a la derecha del men Ayuda de NetBeans tienen un cuadro de
bsqueda. Escriban System all y de las opciones que les aparecen elijan System
(java.lang). Vern que abrirn la clase System y tendrn todo su cdigo fuente
disponible, absolutamente todo y con comentarios. As ustedes podrn ver
cualquier clase de Java ya que como dije antes este lenguaje es de cdigo abierto.

Continuaremos trabajando con esto en la leccin que sigue. Vern que poco a poco Java
se ir mostrando super sencillo. Al principio hay cosas que cuestan pero es, como
siempre
ha
sido,
solo
acostumbrarse
jeje.
NOTAS:

Deberan haber notado ya que Java es sensible a maysculas y minsculas (case

sensitive) tal como lo era Modula2.


El IDE NetBeans est totalmente programado en Java, as que tienen un gran
ejemplo de lo que se puede lograr no?

LECCIN 63: SALIDA Y ENTRADA ESTNDAR EN


JAVA.
SALIDA ESTNDAR BSICA
Hemos visto el clsico Hola mundo en Java y con l se nos han venido encima un
montn de cosas. Adems da la sensacin de que eso de main es complicado y que el
System.out tambin. Por qu no hay un simple WriteString o WriteLn y ya? Adems hay
un montn de palabras raras que todava no sabemos que son: public, static, void Bien,
todo se ir aclarando de a poco a medida que avancemos. Por el momento tendremos
interrogantes que se quedarn colgadas porque no tengo forma de explicarlas sin irme a
temas ms avanzados. Es por este motivo que no pas de Pascal a Java directamente.
Bien, vimos que los programas en Java en vez de mdulos tienen clases. Las clases no
tienen archivos DEF ni MOD sino que se crean en un archivo CLASS que por suerte
NetBeans lo hace solito. Todo el cdigo fuente est en un solo archivo as que nos
olvidamos de eso de tener un archivo de definicin y otro de implementacin, todo est
en un solo lugar para Java.
Tambin vimos que, como un programa puede tener muchas clases, tiene que haber una
que sea la principal para que el programa tenga un punto de partida al ejecutarse. Esta
clase se diferenciar de las dems porque tendr dentro de s un procedimiento llamado
main declarado s o s de esta manera:
Cdigo:

1. public static void main(String[] args)


Dentro de este procedimiento irn las lneas de cdigo fuente de ejecucin del programa
tal como suceda en Modula 2 con el mdulo principal.
Sabemos ya que al igual que en Modula, los literales de Strings van entre comillas dobles
y que NetBeans los pinta en color naranja. La salida estndar est representada por
System.out los cuales tienen para nosotros varios procedimientos y funciones tiles. De
momento solo usaremos print y println.
En Pascal, cuando comenzamos con Write y WriteLn hicimos un ejemplo que mostraba
el texto
Cdigo:

Hice mi primer programa en Pascal.


Logr el clsico Hola Mundo

El cdigo fuente en Pascal para mostrar esta salida era:


Cdigo:

1. WriteLn(Hice mi primer programa en Pascal.);


2. Write(Logr el clsico Hola Mundo.);

En Java sera as:


Cdigo:

1. System.out.println(Hice mi primer programa en Java.);


2. System.out.print(Logr el clsico Hola Mundo.);

Como ven no hay diferencia. Lo nico es que si ustedes corren el cdigo Pascal y el
cdigo Java las salidas sern diferentes ya que el de Pascal mostrar las comillas en
Hola Mundo y el de Java no lo har. Es decir, tendremos esto en la salida de Pascal:
Cdigo:

Hice mi primer programa en Pascal.


Logr el clsico Hola Mundo.

y esto en la salida de Java:


Cdigo:

Hice mi primer programa en Java.


Logr el clsico Hola Mundo.

Ya veremos cmo colocar esas comillas en la salida estndar de Java, ya que no


simplemente agregarlas. Esto es porque las comillas dobles en Java, al igual que
Modula 2, abren y cierran los literales de Strings, por eso si agregamos ms comillas
nuestro argumento de print tendremos un error de sintaxis que NetBeans subrayar
rojo.

es
en
en
en

SECUENCIAS DE ESCAPE:
Justamente por el problema que seal recin con las comillas y por otros tantos, adems
de lograr simplificarnos varias cosas, Java nos provee de ciertos caracteres especiales
para utilizar en los literales de Strings. Como primer ejemplo veremos como lograr la
misma salida anterior en una sola lnea de cdigo:
Cdigo:

1. System.out.print(Hice mi primer programa en Java.\nLogr el


clsico Hola Mundo.);

Vern que solo hay un System.out.print. Sin embargo si ustedes corren ese programa
saldr el texto en dos lneas, tal como si hubiera usado println y print como en el ejemplo
anterior. Si prestan atencin, justo donde hay un salto de lnea en la salida estndar
tenemos en nuestro literal el smbolo \n. Este smbolo representa justamente el fin de
lnea. De este modo este cdigo
Cdigo:

1. System.out.println("Hola Mundo");
puede ser sustituido por
Cdigo:

1. System.out.print("Hola Mundo\n");

La barra diagonal inversa (\) se conoce como carcter de escape. Esta barra indica a
print y a println que se va a imprimir un carcter especial, de modo que dicho carcter
va justo luego de la barra. En este caso, la n minscula indica que lo que se quiere
imprimir es un salto de lnea. De esta manera, si yo quiero que salga en pantalla este
texto:
Cdigo:

He logrado crear
mi primer programa
en el lenguaje Java.

podemos hacerlo con ste cdigo.


Cdigo:

1. System.out.println(He logrado crear);


2. System.out.println(mi primer programa);
3. System.out.println(en el lenguaje Java.);

o bien podemos hacerlo con este cdigo


Cdigo:

1. System.out.print(He logrado crear\nmi primer programa\nen el


lenguaje Java.);
Es importante que quede claro que cada vez que dentro de un literal escribimos \n
imprimiremos
un
salto
de
lnea.
Para imprimir las comillas dobles tenemos la secuencia de escape \. De este modo para
lograr aquella salida que queramos fuera igual que en Pascal el cdigo fuente sera:
Cdigo:

1. System.out.println(Hice mi primer programa en Java.);


2. System.out.print(Logr el clsico \Hola Mundo\.);

As, cada vez que usamos \ Java imprime comillas dobles () en pantalla.
Tenemos un total de cinco secuencias de escape:
\n Nueva lnea. Imprime un carcter de fin de lnea, o sea, baja el cursor una lnea.
\t Tabulacin. Imprime una tabulacin horizonal.
\r Retorno de carro. Vuelve el cursor al inicio de la lnea actual. Todo lo que se imprima

all sobreescribir a los caracteres que ya estaban impresos.


\\ Barra inversa. Imprime una barra inversa (\) en la salida.
\ Doble comilla. Imprime comillas dobles () en la salida.

ENTRADA ESTNDAR E INTRODUCCIN A LAS VARIABLES


EN JAVA:
Hemos visto la salida estndar en Java, lo cual, si lo analizan un poco, no es ms que lo
que ya usbamos en Pascal y es adems bastante ms simple que en Modula 2 ya que no
tenemos que importar nada y podemos imprimir todo en una sola lnea de cdigo. Ahora
bien, la entrada estndar no es algo tan sencillo porque Java no nos provee (dada su
forma de funcionar) de un procedimiento o funcin que directamente lea lo que hemos
escrito en consola, es decir, no tenemos un READ o READLN.
Cmo logramos leer algo de la entrada estndar entonces? Pues bien, tenemos que
importarnos una clase llamada Scanner y crearnos un objeto de esa clase. Como ven, ya
tenemos programacin orientada a objetos solo para lograr una lectura estndar. Otro
motivo para haber hecho un pasaje por Modula antes de llegar a Java. Igualmente por
ahora no se compliquen, solo nos limitaremos a ver cmo funciona y cmo lograr obtener
lecturas desde el teclado sin mayores complicaciones ok?
Esto seguir generando esa sensacin de que Java nos complica todo, pero no es as, es
su funcionamiento, que una vez comprendido ser super intuitivo. Haremos un programa
simple que pida el nombre del usuario y luego lo salude, tal como hicimos en Pascal. Esto
nos llevar a tener variables. Veamos el cdigo fuente:

Cdigo:

1.

import java.util.Scanner;

2.
3.
4.

public class HolaMundo {


public static void main(String[] args){

5.

//Declaracin de variables.

6.

Scanner entradaEstandar= new Scanner(System.in); //Lector de la entrada.

7.

String nombre; //Variable que almacenar lo ledo.

8.
9.

System.out.print("Escribe tu nombre: "); //Un mensaje al usuario.

10.

nombre= entradaEstandar.nextLine(); //Leemos lo ingresado.

11.
12.

System.out.print("Hola "); //Imprimimos un mensaje.

13.

System.out.print(nombre); //Imprimimos el contenido de la variable entrada.

14.

}//Fin del procedimiento main.

15. }//Fin de la clase HolaMundo.

Bueno, se ha complicado un poquito as que como siempre, veamos lnea por lnea lo que
tenemos a fin de que no queden dudas de nada. As que vamos por la lnea 01 donde hay
una importacin. Como dije hoy necesitbamos usar la clase Scanner. En java las
libreras constan de varias clases las cuales se agrupan en paquetes. Un paquete consta
entonces de varias clases y subpaquetes. Bien, la clase Scanner est dentro de un
paquete llamado util que est dentro de un paquete llamado java. Las importaciones en
Java se hacen, al igual que en Modula, al inicio del cdigo fuente antes de declarar la
clase. Usamos la palabra reservada import para decir que queremos importar una clase
o un paquete de clases. La declaracin es entonces as
Cdigo:

1.

import nombreDelPaquete.nombreDelSubpaquete.nombreDelSubpaquete.nombreDeLaClase;

Como ven, lo que se hace es separar por puntos (no espacios) cada nombre de cada
paquete hasta llegar a la clase. Como Scanner est en el paquete util el cual est
dentro del paquete java, tenemos que escribir
Cdigo:

1. import java.util.Scanner;
De momento solo deben saber eso, luego veremos como el IDE nos facilitar la vida con
las importaciones, pero primero tienen que aprender a hacerlas ustedes a mano.
Sigamos. En la lnea 03 tenemos la declaracin de la clase HolaMundo. Como vern, us
la misma clase que ya tenamos solo porque no tena ganas de hacer otro proyecto. En la
lnea 04 tenemos la declaracin del procedimiento main. En la lnea 05 tenemos un
comentario de fin de lnea. Estos comentarios los habamos visto en Pascal y se abren con
el mismo smbolo que en aquel lenguaje (//). Se cierran automticamente con el fin de la
lnea en que se escriben. Como ven, el IDE pinta en gris los comentarios.
En la lnea 06 aparece por primera vez la declaracin de una variable, que encima no es
de un tipo primitivo sino que es de tipo Scanner, es decir, es una variable del tipo de una
clase (como si nosotros nos declarramos una variable del tipo de un mdulo en Modula
2), o sea que es una referencia a un objeto. No me concentrar en este hecho todava
porque no quiero llegar a la programacin orientada a objetos en Java tan rpido, hay
mucho por ver antes.
En Pascal y en Modula 2, a la hora de declarar una variable primero escribamos el
nombre de la variable, luego dos puntos y luego el tipo de datos que almacenara. En
Java va primero el tipo de datos y luego el nombre de la variable sin poner dos puntos.
Por ejemplo, en Pascal una variable nombre del tipo String se declarara as:
Cdigo:

1. nombre: String;

En Modula 2 sera as:


Cdigo:

1. nombre: ARRAY[1..N] OF CHAR;

En Java sera
Cdigo:

1. String nombre;
Algo nuevo es que no necesitamos poner una palabra reservada para declarer variables
en Java como suceda en Pascal y en Modula donde tenamos que poner VAR y luego
declarar las variables. Ahora podemos declararnos una variable en cualquier
momento donde se nos antoje. Si vamos programando y nos damos cuenta que
necesitamos tal o cual variable la declaramos en el momento y ya. No es prolijo, a pesar
de que Java nos permite hacer eso, se suele declarar todas las variables al inicio del
cdigo para que este sea ms legible por otras personas y por uno mismo.
Bien, me declar una variable llamada entradaEstandar del tipo Scanner. Esta variable
ser la que nos devuelva los textos de ingresados por el usuario. En la misma lnea donde
est declarada entradaEstandar la he inicializado asignndole un valor por defecto
mediante
Cdigo:

1. new Scanner(System.in)
Esta asignacin quedar colgada por ahora. Lo importante es que para poder obtener
resultados de la entrada estndar debemos declararnos una variable Scanner tal como yo
lo he hecho.
El smbolo de asignacin en Pascal y Modula era (:=), ahora en Java es simplemente el
(=).
En la lena 07 me declaro una variable llamada nombre del tipo String. En Java volvemos
a tener el tipo String y nos olvidamos del ARRAY OF CHAR de Modula 2. Este tipo es casi
como si fuera un tipo primitivo de Java aunque en realidad no lo es. Por el momento
nosotros lo usaremos como un tipo primitivo ya que podemos hacerlo sin ningn
problema. Luego en la lnea 09 imprimimos un simple mensaje al usuario.
La lnea 10 es la que hace la lectura de la entrada estndar. Vemoslo de forma simple:
Scanner nos provee de una funcin llamada nextLine que no recibe argumentos y
retorna un String que es justamente lo ledo de la entrada estndar. La funcin nextLine
lee toda la lnea completa, como si fuera READLN. A diferencia de READ o READLN,
donde ponamos la variable que recibira los datos como argumento de estos
procedimientos, nextLine lo retorna como funcin, por tanto tenemos que asignar ese
retorno a la variable nombre. Es como si en Pascal en vez de hacer

Cdigo:

1. ReadLn(nombre);

hiciramos
Cdigo:

nombre:= ReadLn();

Sin embargo, nextLine al ser una operacin de Scanner debe usarse mediante un objeto
de esta clase (eso es parte de POO en Java y lo veremos luego). De este modo debo usar
el
objeto
entradaEstandar
para
usar
nexLine
simplemente
escribiendo
entradaEstandar.nextLine().
Entonces, la lnea 10 lo nico que hace es asignar a nombre lo ledo en la entrada
estndar.
La lnea 12 simplemente muestra el mensaje Hola con un espacio al final y la lnea 13
imprime el contenido de la variable nombre. Como ven, println y print puede recibir
variables como argumentos para ser mostrados en pantalla tal como suceda con WriteLn
y Write de Pascal.
Las lneas 14 y 15 cierran los bloques de main y HolaMundo respectivamente con
comentarios que lo aclaran. Dejar comentarios que aclaren qu cierra cada llave ayuda a
mejorar el cdigo, ms all de que NetBeans marca en amarillo las llaves que abren y
cierran un bloque.

EL OPERADOR + EN LOS LITERALES:


Las dos lneas finales que muestran el mensaje al usuario
Cdigo:

1. System.out.print("Hola ");
2. System.out.print(nombre);

Podran haberse sustituido con esta lnea


Cdigo:

1. System.out.print(Hola + nombre);

Esto no era permitido en Pascal y mucho menos en Modula 2. Java nos permite utilizar el
operador + en los literales y hace la unin automticamente. En Pascal tenamos la
salvedad de que un mismo procedimiento Write o WriteLn poda recibir varios
argumentos separados por comas, pero esto en Java y Modula no es posible. De este
modo Java nos provee una forma elegante de solucionarlo.
Si quisiramos que el mensaje final fuera:
Cdigo:

Hola [nombreIngresado]. Es un placer conocerte.


Tendramos bsicamente dos opciones:

Escribimos este cdigo:


Cdigo:

1. System.out.println(Hola );
2. System.out.println(nombre);
3. System.out.println(. Es un placer conocerte);
Escribimos este cdigo:
Cdigo:

1. System.out.println(Hola + nombre + . Es un placer


conocerte.);

Como vern, queda mucho ms corto y ms sencillo el cdigo fuente. As se podra


escribir todo en una sola lnea, no importa cuntos signos de + tengan que utilizar,
cuantas variables hayan, cuantas veces usen cada variable. Pueden armar las frases que
quieran.
Notas interesantes:

Si ponemos el cursor sobre una variable, NetBeans pinta todas las partes del
cdigo donde dicha variable aparece. Adems nos muestra en la barra vertical a la
derecha de la pantalla todos los lugares de modo que si hacemos clic all vamos
directo a la parte del cdigo que queremos.
Si al escribir el nombre de la variable del tipo Scanner ponemos luego un punto,
NetBeans nos muestra todas las operaciones disponibles detallando informacin al
respecto. Podemos subir y bajar por todas ellas a fin de elegir la que necesitamos.

LECCIN 64: EJEMPLO PRCTICO DE LECTURA:


REA DEL TRINGULO.
Vimos hasta ahora en Java un tipo primitivo de datos, el tipo String. Sabemos ya que para
declarar una variable debemos primero poner el tipo y luego el nombre de la variable.
Ahora veremos aquel programa que hicimos en Pascal para calcular el rea y el permetro
del tringulo. Aqu veremos dos tipos primitivos ms. Lo haremos en un proyecto nuevo
llamado AreasYPermetros.
Para crear un nuevo proyecto en NetBeans pueden hacer lo siguiente:

Van a Archivo --> Proyecto Nuevo.


Presionan CTRL + SHIFT + N.
Presionan el botn Proyecto Nuevo de la barra de herramientas.
Hacen clic derecho sobre un espacio en blanco del rea en que se muestran los
proyectos (debajo de la pestaa Proyectos) y eligen Proyecto Nuevo.

Con cualquiera de esas opciones tendrn la ventana que usamos al crear el HolaMundo.
Pongan a su proyecto el nombre AreasYPerimetros. Desmarquen la opcin Crear Main
Class.
Ahora, debajo de la pestaa Proyectos, vemos que aparece el nuevo proyecto creado
marcado en letra negrita. Esto es porque al momento de crearlo estaba marcada la casilla
Set as Main Project (establecer como proyecto principal). Esta casilla est debajo de
Crear Main Class.
Qu significa que un proyecto est marcado como proyecto principal? Pues que al
compilar y/o ejecutar estaremos ejecutando el proyecto principal establecido. De este
modo si ustedes dan clic en el botn Ejecutar Main Project o bien presionan F6, no
estarn corriendo HolaMundo aunque estn mirando su cdigo fuente, sino que
NetBeans intentar correr AreasYPermetros y no podr porque no tiene ninguna clase
principal.
Para cambiar el proyecto establecido como principal simplemente deben hacer clic
derecho sobre su nombre y elegir la opcin Establecer como Proyecto Principal
(puede aparecer Set as Main Project). Con eso ya est. Igualmente ustedes pueden
correr o compilar un proyecto sin establecerlo como proyecto principal; para ello hacen
clic derecho sobre l y elijen Ejecutar (si es que quieren correrlo) o Limpiar y Construir
(si
solo
quieren
compilarlo).
Creemos entonces la clase principal de nuestro proyecto AreasYPerimetros. Es usual
colocar a la clase principal el mismo nombre que tiene el proyecto (tal como yo lo hice
con HolaMundo). No es requerido, es decir que, si yo ahora le pongo a mi clase principal
el nombre Abuela, el programa funcionar sin problemas (en Modula no era as), pero a
la hora de leer el cdigo fuente, sobre todo si hay muchas clases, se facilita encontrar la
clase principal por el nombre. Ms all de eso, NetBeans nos marca con el cono verde de
Play la clase establecida como clase principal.
La ejecucin de nuestro programa debe como quedar la que muestro a continuacin.
Pinto en azul lo que corresponde a la entrada ingresada por el usuario. Los datos
ingresados sern nmeros enteros.
Cita:
Bienvenid@ a reas y Permetros.
Calcularemos el rea y el permetro de:
*Un tringulo.
*Un rectngulo.
*Una circunferencia.
Vamos con el rea del tringulo.
La base ser el primer lado ingresado.
Ingresa la medida de sus lados y su altura: 10 5 7 3
Lado a= 10
Lado b= 5
Lado c= 7

Altura= 3
rea= 15.0
Permetro= 22

Veremos dos formas de hacer esto:

Usando una variable rea y una variable permetro para estos clculos.

Realizando los clculos directamente en println.

Cdigo:
01 import java.util.Scanner;
02
03 public class AreasYPerimetros {
04
public static void main(String[] args){
05
//Declaramos las variables a usar.
06
Scanner entradaEstandar= new Scanner(System.in);
07
int a, b, c, altura, permetro;
08
double rea;
09
10
/*Mostramos el mensaje inicial al usuario. Har todo en una misma lnea
11
* de salida para que se vallan acostumbrando.
12
*/
13
System.out.print("Bienvenid@ a reas y Permetros.\n\n"
14
+ "Calcularemos el rea y el permetro de:\n\n"
15
+ "*Un tringulo.\n*Un rectngulo.\n*Una circunferencia.\n\n"
16
+ "Vamos con el rea del tringulo.\nLa base ser el primer lado"
17
+ " ingresado.\nIngresa la medida de sus lados y su altura: ");
18
19
//Leemos uno a uno los valores ingresados:
20
a= entradaEstandar.nextInt();
21
b= entradaEstandar.nextInt();
22
c= entradaEstandar.nextInt();
23
altura= entradaEstandar.nextInt();
24
25
/*Consumimos el fin de lnea, tal como hacamos con ReadLn en Pascal y
26
* con SkipLine en Modula 2. En Java es usar nextLine solo.
27
*/
28
entradaEstandar.nextLine();
29
30
rea= a*altura/2.0;
31
permetro= a + b + c;
32
33
System.out.println("\nLado a= " + a + "\nLado b= " + b + "\nLado c= " + c
34
+ "\nAltura= " + altura + "\n\nrea= " + rea + "\nPermetro= "
35
+ permetro);
36
}//Fin del procedimiento main.
37 }//Fin de la clase AreasYPerimetros.

Este cdigo es apenas ms complejo que lo que hemos venido viendo, pero no ms
complejo que lo que ustedes ya saben utilizar. Veamos las lneas importantes de este
cdigo
nada
ms
ya
que
hay
mucho
que
ya
he
explicado.
Vamos entonces directo a la lnea 07 donde tenemos una declaracin de varias variables
del tipo int, el cual es un tipo primitivo de Java y se corresponde con el tipo INTEGER de
Pascal y Modula con la enorme diferencia de que admite valores mucho mayores
(veremos esto luego). Como ya saben, en Java para declarar variables primero va el tipo
de datos y luego la variable. Al igual que en los lenguajes anteriores, en Java podemos
declarar varias variables de un mismo tipo separndolas por coma. As, las variables del
tipo int declaradas son a, b, c, altura y permetro.
En la lnea 08 tenemos otra declaracin de variable para una llamada rea del tipo
primitivo double. Este tipo se corresponde con el tipo REAL de Modula y Pascal, salvo
tambin
que
admite
valores
muchsimo
mayores.
Como vern, sigo usando la vieja prctica de declarar todas las variables al inicio del

cdigo. Por el momento siempre estoy haciendo las declaraciones de variables dentro del
propio procedimiento main, es decir que son variables locales a l. Como por ahora
siempre estaremos trabajando dentro de dicho procedimiento no nos complicaremos con
variables globales ni mucho menos.
Entre las lneas 10 y 12 tenemos un bloque de comentarios multilnea. Este es el tipo de
comentarios que usbamos en Modula el cual comenzaba con (* y cerraba *). En Pascal
tambin se abran y cerraban con dichos smbolos o bien con las llaves {}. En Java los
comentarios multilnea se abren con /* y se cierran con */. Este es el segundo tipo de
comentarios que posee Java y el segundo tipo de comentarios que ustedes conocen. Este
lenguaje integra un nuevo tipo de cometarios conocidos como javadoc, pero los veremos
ms
adelante.
Luego entre las lneas 13 y 17 tenemos una impresin en pantalla de todo el texto que se
debe mostrar al usuario tal como lo describ en el ejemplo. Podra haber usado varios
println para lograr la misma salida, sin embargo quiero que vean cmo podemos escribir
una salida muy larga en un solo print o println uniendo los trozos de texto con signos de
suma (+). Eso es lo ms comn en Java. Modula no nos permita esto y Pascal tampoco.
La facilidad que nos da la secuencia de escape \n es muy valorable, ahorramos mucho
tiempo.
Ahora viene la parte en que leemos los datos. Esta vez no us nexLine ya que no quera
leer toda la lnea completa y adems no quera recibir algo de tipo String, sino que quera
leer de a uno los nmeros ingresados por el usuario. Para esto en vez de usar nexLine
usamos nexInt, que justamente lee un entero (algo del tipo primitivo int) en la entrada y
nos lo devuelve. No consume toda la lnea, sino que lee un entero y luego deja el cursor
justo adelante del siguiente espacio. Cabe destacar que para usar nextInt lo que el
usuario ingres debe ser justamente un nmero del tipo int, de lo contrario Java nos
lanzar una excepcin del tipo InputMismatchException que significa Excepcin de
falta de coincidencia en la entrada (veremos excepciones ms adelante) y nos mostrar
un mensaje como este en la salida de la consola:
Cita:
Exception in thread "main" java.util.InputMismatchException
at java.util.Scanner.throwFor(Scanner.java:840)
at java.util.Scanner.next(Scanner.java:1461)
at java.util.Scanner.nextInt(Scanner.java:2091)
at java.util.Scanner.nextInt(Scanner.java:2050)
at AreasYPerimetros.main(AreasYPerimetros.java:20)
Java Result: 1
GENERACIN CORRECTA (total time: 5 seconds)

Estos informes de errores nos ayudan mucho a la hora de detectar problemas. Lo que
est en rojo indica, en cada rengln, el paquete, la clase y la operacin en la que se ha
producido el error separando cada dato por un punto porque justamente est indicando
paquetes. Lo que est en azul es un enlace hacia la clase indicada en la lnea exacta
donde sucedi el problema (si hacemos clic en l nos lleva justo a donde se detect el
error). Esto hay que leerlo desde abajo hacia arriba (por un tema de herencia). Si se fijan,
el ltimo error indicado est en la clase AreasYPerimetros en la operacin main, ms
explcitamente en la lnea 20. Justo la lnea 20 es donde se lee el primer entero y se le
asigna el valor a la variable a. El problema fue que el usuario no ingres algo del tipo int
y por eso nuestro programa cay. Luego el error nos lleva a la lnea 2050 de la clase
Scanner y as podemos navegar hasta la lnea 840 de dicha clase que es donde se lanz
la excepcin. De momento sabemos que el problema es el ingreso de datos y con eso nos
basta
para
proseguir.
Debajo de todo el informe indica GENERACIN CORRECTA ya que el programa compila
bien y por tanto el archivo .class fue creado; el problema que hubo fue en tiempo de
ejecucin.

Hasta la lnea 23 de nuestro cdigo tenemos las asignaciones de los nmeros ingresados
por el usuario. Dichos nmeros pueden ingresarse de a uno separando por espacios o
bien presionando ENTER. Es como cuando utilizbamos READ en Pascal con una variable
INTEGER para leer de a uno los enteros.
Al igual que suceda en Pascal, tenemos que consumir el fin de lnea luego de leer algo
que no lo consume. Esto en aquel lenguaje lo hacamos colocando un READLN solito. En
Modula lo hacamos con SkipLine. Pues en Java lo hacemos colocando nextLine
solamente. Recuerden que las operaciones que estamos utilizando para leer son de la
clase Scanner y por eso se hacen a travz del objeto Scanner que nosotros nos creamos.
En la lnea 28 consumimos el fin de lnea.
En la lnea 30 tenemos una sentencia de asignacin donde le damos a la variable rea el
valor de multiplicar la variable a por la variable altura y dividir esto entre 2. En Pascal o
Modula esta asignacin sera:
Cdigo:

area:= a*altura/2.0;

En Java lo nico que cambia es que el signo de asignacin (:=) cambia por (=). Algo que
cabe destacar es que poda haber puesto 2 en vez de 2.0. La diferencia es que uno es un
nmero entero y el otro es un nmero real. En Pascal y Modula la operacin / era
estrictamente del tipo REAL. En Java eso no es as, al menos no en las versiones actuales.
Si todos los operandos de la operacin matemtica son del tipo int pues Java
transformar el resultado de la operacin / a tipo int. Por ejemplo, sabemos que la
variable rea es del tipo double (casi equivalente al tipo REAL de Pascal y Modula) y que
a y altura son del tipo int. Si yo hago aquella asignacin de esta manera
Cdigo:

rea= a*altura/2;

estoy dejando todos los operandos del tipo int. Como no hay ninguno del tipo double Java
hace la operacin / retornando un int tal como si fuera DIV en Modula o Pacal. Luego
asigna eso a la variable rea; como esta es double Java transforma el resultado int a
double agregando un 0 luego de la coma. El problema de esto es que perdemos precisin.
Veamos un ejemplo:
Supongamos que:
a= 7
altura= 3
Si hacemos la operacin de la segunda forma (todos int) tenemos que:
Cdigo:

7*3/2= 10

Luego Java asignar el valor entero 10 a la variable rea pero dejndolo como 10.0
para que sea double. Eso claramente est mal, aquella cuenta debe dar 10.5. Para
que / funcione como divisin real debe haber algn real en los operandos, por eso
pongo el 2 como 2.0.
Resumiendo, en Pascal y Modula tenamos DIV para divisin entera y / para divisin
REAL. En Java tenemos solo /, y esta funciona como divisin entera si todos los
operandos son enteros y como divisin real si hay al menos un operando que del tipo
real (double para Java).

Cabe destacar que el smbolo de multiplicacin sigue siendo el viejo y querido


asterisco (*).
En la lnea 31 asignamos a la variable permetro la suma de los lados del tringulo. En
la lnea 33 comienza el ltimo println el cual en una sola instruccin imprime todo el
mensaje final. A diferencia del mensaje inicial, donde todo lo que unamos con el
signo de suma (+) era del tipo String, ahora tenemos tanto String como nmeros.
Java nos permite realizar esta mezcla ya que el signo de suma (+) est sobrecargado,
es decir, tiene dos funciones
Sumar nmeros matemticamente.
Concatenar cadenas de caracteres.
Al encontrar Strings y nmeros mezclados Java transforma los nmeros a Strings y
los concatena con las cadenas existentes formando las frases que queremos. De este
modo, algo como esto
Cdigo:

System.out.prinln(El resultado es + resultado);

imprimir, si por ejemplo la variable resultado vale 25, el mensaje:


Cdigo:

El resultado es 25

En Pascal podamos hacer esto en una instruccin ya que Write y WriteLn permitan una
lista variable de argumentos de diversos tipos. En Modula tenamos que utilizar mltiples
instrucciones para imprimir los datos en funcin del tipo al que pertenecan. Java nos da
una mayor soltura incluso que Pascal al sobrecargar el smbolo (+).
Hay un pequeo detalle con esto. El programa anterior se poda hacer sin utilizar las
variables rea y permetro ya que podamos realizar los clculos directamente en la
instruccin de salida:
Cdigo:

System.out.println("\nLado a= " + a + "\nLado b= " + b +


"\nLado c= " + c + "\nAltura= " + altura +
"\n\nrea= " + a*altura/2.0 + "\nPermetro= "+ (a+b+c));

Como ven he realizado los clculos directamente en la instruccin de salida. La operacin


Cdigo:

a*altura/2.0

no es problema porque al tener smbolos de multiplicacin (*) y/o divisin (/) y/o resta (-),
Java detecta que es una operacin matemtica, la resuelve, y luego concatena el
resultado a la cadena de salida. Sin embargo, la ltima operacin que corresponde al
clculo del permetro DEBE llevar los parntesis para que le den precedencia. El tema es
que como es una operacin que solo tiene el smbolo (+) y en este caso dicho smbolo
tiene dos funcionalidades (sumar nmeros y concatenar cadenas de caracteres), Java
necesita saber cul de las dos funcionalidades queremos usar.
Supongamos esta instruccin:
Cdigo:

System.out.println(El permetro es + a + b + c);

Si a=10, b= 11 y c= 13 el permetro es 34. Sin embargo la salida que obtendrn es esta


Cdigo:

El permetro es 101113

Qu pas? Pues como no era explcito, Java utiliz la funcionalidad de concatenar


caracteres del operador (+) porque haba un String (literal) en la instruccin de salida y
pues en realidad tom los nmeros como si fueran Strings. Para solucionar eso la
instruccin debera ser
Cdigo:

System.out.println(El permetro es + (a + b + c));

Al tener los parntesis, Java detecta la precedencia de la operacin y, como todo lo que
hay entre parntesis corresponde a variables numricas, realiza la cuenta matemtica y
luego concatena el resultado al String que est a la izquierda.
Con esto cerramos el ejemplo del rea del tringulo no sin dejar un ejercicio:
NOTAS: El objeto del tipo Scanner tiene una operacin next casi para cualquier tipo
primitivo que queramos leer:

nextBoolean: Lee el siguiente booleano en la entrada estndar.


nextByte: Lee el siguiente valor del tipo byte.
nextDouble: Lee el siguiente nmero real.
nextFloat: Lee el siguiente nmero real.
nextInt: Lee el siguiente nmero entero.
nextLine: Devuelve un String con el contenido de toda la lnea.
nextLong: Lee el siguiente nmero entero.
nextShort: Lee el siguiente nmero entero.

No tenemos una operacin para leer datos del tipo char. Esto tiene una solucin sencilla
mediante el trabajo con el tipo String, pero la veremos ms adelante.
Ejercicio: Completar el programa anterior para que adems del rea y el permetro del
tringulo calcule tambin el rea y el permetro de un rectngulo y de una circunferencia.
Les dejo a continuacin un ejemplo de ejecucin, pintando en azul lo que corresponde a
la entrada ingresada por el usuario:
Cita:
Bienvenid@ a reas y Permetros.
Calcularemos el rea y el permetro de:
*Un tringulo.
*Un rectngulo.
*Una circunferencia.
Vamos con el rea del tringulo.
La base ser el primer lado ingresado.
Ingresa la medida de sus lados y su altura: 10 5 7 3
Lado a= 10
Lado b= 5
Lado c= 7

Altura= 3
rea= 15.0
Permetro= 22
Ahora vamos con el rea y el permetro del rectngulo:
Ingresa la medida de la base y la altura: 10 5
Base= 10
Altura= 5
rea= 50
Permetro= 30
Solo falta la circunferencia.
Ingresa la medida del radio: 10
Radio= 10
rea= 314
Permetro= 62.8
Gracias por usar AreasYPerimetros.

NOTAS:

El rea de una circunferencia se calcula como r*r*PI donde r es el radio y PI es


3.14. De momento no usaremos constantes porque no lo he explicado.
El permetro de una circunferencia es d*PI donde d es el dimetro.
El dimetro de una circunferencia se calcula como r*2 donde r es el radio.

La salida de su programa debe ser idntica a la mostrada en el ejemplo. Esto ser una
enorme prctica para ustedes con la cual comenzarn a manejar varios aspectos de Java.

LECCIN
65:
TIPOS,
DECLARACIONES Y SELECCIN

OPERADORES,

En esta leccin veremos las palabras reservadas de Java, un poco ms sobre declaracin
de variables aadiendo adems las constantes, tipos primitivos y sus rangos de datos,
operadores aritmticos y relacionales para as llegar a la seleccin, es decir, a los if y a
algo parecido al CASE.

PALABRAS RESERVADAS Y TIPOS PRIMITIVOS DE JAVA


Al igual que cualquier lenguaje Java tiene sus propias palabras reservadas. Como estas
tienen un significado propio para el lenguaje no pueden ser utilizadas como
identificadores para nada que queramos usar, tal como variables, constantes, clases,
operaciones, etc.
Les dejo un listado de las palabras reservadas que existen en Java hoy da simplemente
para que lo tengan presente:
abstract default if private this
boolean do implements protected throw
break double import public throws
byte else instanceof return transient
case extends int short try
catch final interface static void
char finally long strictfp volatile
class float native super while
const for new switch
continue goto package synchronized

Asimismo tenemos tambin los tipos primitivos de datos de los cuales conocemos dos
hasta ahora: int y double. Los tipos primitivos son aquellos tipos de datos predefinidos
por el lenguaje. Estos datos se almacenan directamente en memoria ocupando un cierto
espacio ya establecido. Normalmente estos tipos de datos refieren a nmeros, caracteres
y booleanos. Veamos entonces qu tipos de datos primitivos nos da Java para trabajar:

boolean: El tpico booleano. Puede valer true o false. Ocupa 1 bit de memoria.
char: Un carcter Unicode, como los que ya conocemos. Ocupan 16 bits de
memoria.
byte: Un nmero entero con signo. Va desde -128 hasta 128. Ocupan 8 bits de
memoria.
short: Un nmero entero con signo. Este tipo es idntico al tipo INTEGER de
Pascal y Modula ya que tiene el mismo rango de valores y cada variable de este
tipo ocupa tambin 16 bits de memoria. Va desde -32768 hasta 32767.
int: Un nmero entero con signo. Va desde -2147483648 hasta 214748647.
Ocupan 32 bits de memoria. Como ven, ya tenemos un rango mucho mayor que
en Pascal o Modula.
long: Un nmero entero con signo. Va desde -9223372036854775808 hasta
92233720368547707. Ocupan 64 bits de memoria. Un super rango numrico.
float: Un nmero de coma flotante. Este tipo es idntico al tipo REAL de Pascal o
Modula. Tienen un rango comprendido entre +-3.40282347E+38 y +1.40239846E-45. Tiene una precisin simple. Ocupa 32 bits de memoria.
double: Un nmero de coma flotante con doble precisin. Va desde
+-1.79769313486231570E+308 hasta +-4.94065645841246544E-324. Ocupan 64
bits de memoria.

Como ven, los tipos numricos nos dan mayores rangos con los que trabajar respecto a
los que tenamos antes con Pascal y Modula. Hay que tener cuidado con la compatibilidad

de estos tipos, pero me gustara que ustedes mismos hicieran pequeas pruebas
declarando variables de distintos tipos y asignen a unas los valores de otras.
Por ejemplo, si yo me declaro una variable llamada real del tipo double y otra llamada
entero del tipo int, puedo hacer esto:
Cdigo:

real= entero;

Sin embargo, si lo hago a la inversa NetBeans subrayar en rojo la asignacin y si


posamos el cursor del mouse sobre ella veremos el mensaje:
Cita:

possible loss of precision


required: int
found: double

Tenemos una forma de que Java vea una variable double como int para poder hacer
una asignacin que en Pascal o Modula era simplemente incompatible. Esta forma se
conoce como casteo, pero la veremos ms adelante.
Algo a destacar es que el tipo String no aparece como tipo primitivo de datos y
justamente es porque no lo es. Un String es una concatenacin de caracteres, es decir
que, un String es la unin de varios datos de tipo char, el cual s es un dato primitivo.

OPERADORES ARITMTICOS DE JAVA


Como era de esperarse y adems como ya vimos, Java tiene sus operadores aritmticos,
es decir, los smbolos que nos sirven para realizar operaciones matemticas. Estos por lo
general son los mismos en casi todos los lenguajes, siempre con alguna salvedad propia.
En Java no tenemos mucha diferencia de lo que eran los operadores matemticos de
Pascal y Modula excepto por DIV y MOD que ahora ya no existen con esas palabras. Les
pido que lean estos detalles porque hay sutilezas importantes y luego preguntan cosas
que estn explicadas aqu si?:
+ (Suma): Simplemente realiza la suma de sus operandos.
- (Resta): Simplemente realiza la del segundo operando al primer operando.
* (Producto o multiplicacin): Realiza el producto de sus operandos.
/ (Divisin o cociente): Realiza la divisin de sus operandos. Esta operacin funciona
como divisin real (tal como en Pascal o Modula) si hay al menos un operando de tipo real
(float y double en Java). Si ambos operandos son enteros (short, int y long en Java) esta
operacin funciona como si fuera la operacin DIV de Pascal o Modula, es decir, divisin
entera.
% (Mdulo o resto): Esta operacin equivale a MOD en Pascal o Modula.
En las operaciones aritmticas siempre pueden estar presentes los parntesis para dar
precedencia a una operacin u otra, tal como siempre ha sido. No me detendr a explicar
eso.
Veamos en Java aquel ejemplo de Pascal que dado un nmero de cuatro cifras lo
desglosaba y mostraba el resultado de dichas cifras. Recordemos el cdigo Pascal:
Cdigo:

1 {El siguiente programa desglosar un nmero de cuatro cifras


2 en sus cuatro nmeros distintos, uno por cada cifra y realizar
3 la suma entre ellas}
4 PROGRAM SumaCifras;
5
6 Var
7
numero: integer; //El valor que ser ledo.
8
c1, c2, c3, c4: integer;//Una variable para cada cifra.
9
10 BEGIN
11 write('Ingresa un nmero de cuatro cifras: ');
12 readln(numero); //Leemos el nmero de 4 cifras.
13
14 (*Asignamos a cada variable el valor de la cifra que le corresponde*)
15 c1:= numero mod 10;
16 c2:= (numero mod 100) div 10;
17 c3:= (numero mod 1000) div 100;
18 c4:= numero div 1000;
19
20 //Mostramos el resultado al usuario.
21 write('El resultado de sumar ',c4,'+',c3,'+',c2,'+',c1,' es: ',c1+c2+c3+c4);
22 END.

Ahora veamos el cdigo Java:


Cdigo:
import java.util.Scanner;
/*El siguiente programa desglosar un nmero de cuatro cifras
en sus cuatro nmeros distintos, uno por cada cifra y realizar
la suma entre ellas*/
public class EjemploMOD {
public static void main(String[] args){
Scanner entrada= new Scanner(System.in);
int numero, c1, c2, c3, c4;
System.out.print("Ingresa un nmero de cuatro cifras: ");
numero= entrada.nextInt();
c1=
c2=
c3=
c4=

numero % 10;
(numero % 100)/10;
(numero % 1000) / 100;
numero / 1000;

System.out.println("El resultado de sumar " + c4 + "+"


+ c3 + "+" + c2 + "+" + c1 + " es " + (c1+c2+c3+c4));
}//Fin de main.
}//Fin de la clase EjemploMOD.

El cdigo es casi exacto al de Pascal y creo yo que muy fcil de comprender. Comparen
ambos y saquen sus propias conclusiones.

DECLARACIN DE VARIABLES Y CONSTANTES. SELECCIN


EN JAVA
Ya hemos visto la declaracin de variables en Java, solo nos queda un pequeo detalle
acerca de esto y es que podemos declarar variables a la vez que las inicializamos (es lo
que hacemos con la variable del tipo Scanner). Tambin veremos como declarar
constantes en Java para pasar luego a la seleccin, es decir, a los viejos y queridos if.

DECLARACIN DE VARIABLES CON INICIALIZACIN CONJUNTA:


Como ya sabemos, las variables se declaran as:
Cdigo:

TipoDeDatos identificadorVariable;

Podemos adems declarar muchas variables del mismo tipo separadas por comas
adems de que Java nos permite declarar las variables por cualquier parte del cdigo
siempre que las declaremos antes de usarlas. Bien, como ya saben siempre que vamos a
usar una variable para alguna operacin y no sabemos qu valor tendr ya que no lo
leeremos de la entrada (por ejemplo un contador para iterar) debemos inicializarlas.
Veamos un ejemplo donde me declaro una variable del tipo int llamada i y la inicializo en
0:
Cdigo:

int i;
i= 0;

Bien, eso no tiene nada de nuevo, primero me declar la variable y luego la inicialic.
Java tambin me permite hacer esto para simplificar el cdigo:
Cdigo:

int i=0;

Como ven he declara la variable y a la vez le he dado un valor inicial. Supongamos que
quiero declarar muchas variables del tipo int y quiero inicializar algunas s y otras no.
Podemos hacer todo por separado o todo junto as:
Cdigo:

int i=0, j=8, altura, base, suma= 0;

Java nos da una libertad total a la hora de declarar variables. All tenemos tres que han
sido inicializadas y dos que no. No tenemos que respetar ningn orden ni mucho menos.
Se suele declarar a las variables que no inicializamos por un lado, y por otro lado a las
que s para dejar el cdigo ms claro, es decir, algo como esto:
Cdigo:

int i=0, j=8, suma= 0;


int altrua, base;

Esto es muy relativo ya que se pueden agrupar las variables segn el uso que se les dar.
En fin, cada uno escribe sus programas como ms le guste. Dejen buenos comentarios y
ya.
Algo importante es que a veces suele ser necesario en Java inicializar variables del tipo
String dada la soltura de este lenguaje para el trabajo con cadenas de caracteres. Con
qu valor inicializo un String? Pues a menos que fuese lo que necesitamos podemos
inicializar un String con algn valor que elijamos, pero Java nos provee la posibilidad de
inicializar un String con un valor nulo el cual es . S, el String nulo es abrir y cerrar
comillas. Por ejemplo:
Cdigo:

String palabra= ;

NOTA: El tipo char de Java utiliza comillas simples (como los Strings de Pascal) y no
dobles porque sino seran Strings. Ejemplo:
Cdigo:

char letra= A;

DECLARACIN DE CONSTANTES:
Como ya saben, las constantes son variables que no cambian de valor, por eso est mal
llamarlas variables. En Pascal y Modula las declarbamos debajo de la palabra CONST.
Como no variaban haca falta inicializarlas en la misma declaracin. Algo interesante es
que no le asignbamos el tipo ya que este quedaba implcito en el valor que le dbamos
a la constante.
En Java, al igual que no existe VAR tampoco existe CONST y al igual que con las variables
podemos declarar las constantes en cualquier lado. Es necesario poner el tipo de datos
que contendr. La declaracin de constantes es igual a la de variables solo que
anteponemos la palabra reservada final:
Cdigo:

final int MI_CONSTANTE= 20;

La declaracin de constantes en Java sigue siendo una declaracin de variables y por


tanto respeta las mismas reglas salvo la excepcin de que a las constantes hay que
inicializarlas s o s. De este modo podemos declarar muchas constantes en una sola lnea
tal como con las variables. En Java entonces las constantes pasan a ser variables
finales.
Algo importante es que las constantes suelen declararse siempre en mayscula. Es una
convencin, algo que ayuda dentro del cdigo a distinguirlas de las variables. Java nos
deja darles el nombre que queramos.
Como dato interesante es que podemos declarar constantes del tipo String, por ejemplo:
Cdigo:

final String MI_CADENA= Alguna cadena til;

Ejercicio: Transcriban este cdigo Pascal a Java:


Cdigo:

1 PROGRAM preciosIVA;
2
3 Const
4 iva= 23;
5
6 Var
7 harina, leche, azucar, sal, arroz: real;//Precios de los productos.
8 porcentaje: real; //Para calcular cunto se debe sumar al precio.
9
10 BEGIN
11
12 //Mostramos mensajes al usuario y leemos los datos desde la entrada.
13 write('Precio HARINA : ');
14 readln(harina);
15 write('Precio LECHE : ');
16 readln(leche);
17 write('Precio AZUCAR : ');
18 readln(azucar);
19 write('Precio SAL : ');
20 readln(sal);
21 write('Precio ARRZ : ');
22 readln(arroz);
23
24 //Dejamos una lnea en blanco.
25 writeln;
26
27 //Calculamos el porcentaje de IVA para harina.
28 porcentaje:= harina*iva/100;
29 //Mostramos el nuevo precio al usuario.

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

writeln('HARINA + IVA : ',harina+porcentaje:2:2);


//Calculamos el porcentaje de IVA para leche.
porcentaje:= leche*iva/100;
//Mostramos el nuevo precio al usuario.
writeln('LECHE + IVA : ',leche+porcentaje:2:2);
//Calculamos el porcentaje de IVA para azucar.
porcentaje:= azucar*iva/100;
//Mostramos el nuevo precio al usuario.
writeln('AZUCAR + IVA : ',azucar+porcentaje:2:2);
//Calculamos el porcentaje de IVA para sal.
porcentaje:= sal*iva/100;
//Mostramos el nuevo precio al usuario.
writeln('SAL + IVA : ',sal+porcentaje:2:2);
//Calculamos el porcentaje de IVA para arroz.
porcentaje:= arroz*iva/100;
//Mostramos el nuevo precio al usuario.
writeln('ARROZ + IVA : ',arroz+porcentaje:2:2);
END.

En un programa muy sencillo.

OPERADORES RELACIONALES DE JAVA PARA


EXPRESIONES BOOLEANAS:
Veamos como hacemos en Java para comparar nmeros y dems:

Como ven solo han cambiado los operadores de igualdad y diferencia con respecto a los
que tenamos en Pascal y Modula.

SELECCIN SIMPLE CON IF:


En Java tambin tenemos el viejo y querido if, solo que ya no es IFTHEN como en Pascal
o Modula, ahora es solo if. Su uso es as:
Cdigo:

if (condicin)
instruccin;

Ese es un if super sencillo, es decir, con una sola instruccin. Si hacen memoria, en
Pascal podamos tener IF con una sola instruccin al que no tenamos que ponerle BEGIN

y END porque no haca falta. En Java es igual, si el if tiene una sola instruccin podemos
poner un bloque de llaves {} o no, es decir que aquel if poda haber sido
Cdigo:

if (condicin){
instruccin;
}

De este modo, la forma general de un if en Java sera:


Cdigo:

if (condicin){
Instruccin1;
Instruccin2;
...
InstruccinN
}

Algo super importante en Java es que la condicin SIEMPRE va entre parntesis, no hay
excepcin a eso, de otro modo tendrn un error de sintaxis.
Veamos un ejemplo sencillo:
Cdigo:

import java.util.Scanner;
public class EjemploIF {
public static void main(String[] args){
Scanner entrada= new Scanner(System.in);
int n1, n2;
System.out.print("Ingrese dos nmeros enteros: ");
n1= entrada.nextInt();
n2= entrada.nextInt();
entrada.nextLine();
if(n1<n2)
System.out.println("El primero es menor que el segundo.");
if(n1==n2)
System.out.println("Ambos nmeros son iguales.");
if(n1>n2)
System.out.println("El primero es mayor que el segundo.");
}//Fin de main.
}//Fin de EjemploIF.

SELECCIN DOBLE CON IFELSE:


Como no poda ser de otro modo, si tenemos if tenemos else. Como ahora perdimos el
THEN, en vez de IFTHEN e IFTHENELSE tenemos if e ifelse. La idea es
exactamente la misma que en Pascal y Mdula; dada una condicin si esta se cumple
hacemos lo que est en el bloque del if y sino lo que est en el else.
Cambien el cdigo anterior por este:

Cdigo:

if(n1<n2)
System.out.println("El primero es menor que el segundo.");
else if(n1==n2)
System.out.println("Ambos nmeros son iguales.");
else
System.out.println("El primero es mayor que el segundo.");

Como vern, ya no tenemos ms ELSIF. En caso de necesitar ms de una instruccin


deben usar llaves para crear bloques de instrucciones.
Lo dems debera resultarles intuitivo. Prueben ustedes mismos.

OPERADORES LGICOS EN JAVA:


Tambin conocidos como operadores booleanos. Estos no son ms que aquellos
operadores que nos permiten componer condiciones, es decir, los ya conocidos NOT, OR y
AND. Veamos cmo escribimos estos operadores en Java, recordando a la vez las viejas y
queridas tablas de verdad.

Operador NOT lgico (!):


Niega la condicin que le sigue. Este operador se conoce como operador lgico de
negacin. En Pascal y Mdula era NOT, ahora es !.

Operador AND condicional (&&):


Ahora el AND se ha transformado &&. Este operador funciona exactamente igual que AND
en Pascal o Modula, incluso evaluando por circuito corto. Si no lo recuerdan, AND evala
dos condiciones y devuelve TRUE si ambas condiciones son verdaderas. Como la
evaluacin es por circuito corto si la primera condicin es FALSE entonces ya no se evala
la segunda porque sin importar su valor el resultado ser FALSE. Veamos la tabla de
verdad:

Operador OR condicional (||):


Lo que antes era OR ahora se escribe con las dos barras verticales ||. Este operador
funciona de forma idntica que en Pascal o Modula, es decir, devuelve TRUE si al menos
una de las condiciones es verdadera. Si la primera condicin es TRUE ya no se evala la
segunda porque sin importar su valor el resultado ser TRUE; en contraparte, si la
primera condicin es FALSE entonces s se evala la segunda.

Java introduce adems tres operadores booleanos nuevos:

Operador AND lgico booleano (&):


Idntico al operador && con la salvedad de que evala por circuito completo, es decir,
siempre se evalan ambos operandos sin importar sus valores. La tabla de verdad es
idntica a la de &&. Puede resultar til en algunas circunstancias, aunque no lo usaremos
mucho.

Operador OR inclusivo lgico booleano (|):


El mismo caso. Este operador es idntico al operador || salvo que evala siempre por
circuito completo. La tabla de verdad es exactamente la misma.

Operador OR exclusivo lgico booleano (^):


Ahora el operador ^ ya no se usar para punteros (porque Java no nos permite usarlos)
sino que ser un operador booleano. Este OR ser TRUE s y solo s uno de los operandos
es TRUE y el otro FALSE. Si ambos son TRUE o ambos son FALSE entonces devuelve
FALSE. Veamos la tabla de verdad:

Este operador no tiene ms remedio que evaluar por circuito completo.


Estamos de acuerdo en que podemos lograr este resultado componiendo || y && como
lo hacamos en Pascal y Modula?

SELECCIN MLTIPLE CON SWITCH:


Ya no tenemos ms el CASEELSE, ahora tenemos switch. Esta instruccin es
prcticamente idntica al CASE de Pascal o el de Modula excepto por algn detalle que ya
veremos. Recordemos las declaraciones que usbamos con CASE hasta ahora:
En Pascal:

Cdigo:

CASE variable OF
Constante1: BEGIN
Instrucciones;
END;
...
ConstanteN: BEGIN
Instrucciones;
END;
ELSE
BEGIN
Instrucciones;
END;
END;

Debemos recordar que en cada etiqueta (constante) podamos omitir los bloques
BEGIN/END si tenan solo una instruccin. La variable deba ser de un tipo ordinal, por
tanto no servan Strings, nmeros reales ni tipos definidos por nosotros mismos a menos
que
fueran
enumerados.
En Modula 2:
Cdigo:

CASE variable OF
Constante1: Instruccion1;
...
InstruccinX|
...
ConstanteN: Instruccin1;
...
InstruccinY|
ELSE
Instruccin1;
...
InstruccinZ|
END;

Igual que el CASE de Pascal salvo que ya no existen los bloques BEGIN/END. Para cada
etiqueta las instrucciones se separaban por punto y coma salvo la ltima que se cerraba
con la barra vertical |. Por lo dems funcionaba igual.
En ambos casos la etiqueta ELSE no era obligatoria sino que serva para hacer algo en
caso de que la variable no tomara el valor de ninguna de las etiquetas. Podamos omitir
perfectamente el ELSE y en caso de que sucediera lo anteriormente dicho el CASE no
haca nada.
La instruccin switch de Java hereda un aspecto del CASE de Modula: tenemos algo que
cierra todas las etiquetas. En Modula era la barra |, en Java ser la palabra reservada
break. Veamos la declaracin genrica de switch y luego transformaremos un CASE para
que quede claro:
Cdigo:

switch (variable){
case etiqueta1: Instruccin(es);
break;
case etiqueta2: Intruccin(es);
break;
...
}

Como ven es casi lo mismo. La variable va entre parntesis s o s. Antes de cada etiqueta
debe ir la palabra case y luego los dos puntos. Por cada etiqueta podemos tener tantas
instrucciones como queramos, incluyendo if y sentencias de repeticin. Cada etiqueta
debe (en realidad puede) finalizar con break.
Ejemplo:

Supongamos que la variable num es de tipo INTEGER en Pascal y Modula y de tipo int en
Java:

CASE Pascal:

Cdigo:

CASE num OF
1: WriteLn(El nmero es el 1.);
2: Begin
WriteLn(El nmero es el 2.);
Write(No me gusta mucho ese nmero.);
End;
3: WriteLn(El tres tambin me gusta.);
END;

CASE Modula:
Cdigo:

CASE num OF
1: WriteString(El nmero es el 1.)|
2: WriteString(El nmero es el 2.); WriteLn;
WriteString(No me gusta mucho ese nmero.)|
3: WriteString(El tres tambin me gusta.)|
END;

Switch:

Cdigo:

switch (num){
case 1: System.out.println(El nmero es el 1.); break;
case 2: System.out.println(El nmero es el 2.);
System.out.println(No me gusta mucho ese nmero.);
break;
case 3: System.out.println(El tres tambin me gusta.); break;
}

Y el ELSE donde queda con switch? Pues switch en vez de ELSE tiene una instruccin
llamada default que es exactamente lo mismo. Si la variable no toma el valor de ninguna
de las etiquetas case entonces entramos en el default. Con el mismo ejemplo tendramos:
Cdigo:

switch (num){
case 1: System.out.println(El nmero es el 1.); break;
case 2: System.out.println(El nmero es el 2.);
System.out.println(No me gusta mucho ese nmero.);
break;
case 3: System.out.println(El tres tambin me gusta.); break;
default: System.out.println(No se eligi ni 1, ni 2, ni 3.);
System.out.println(Default y ELSE son lo mismo.);
break;
}

Qu pasa si no usamos break?


Si prueban escribir las etiquetas de switch sin usar break vern que el cdigo compila
perfectamente. Bien, a diferencia de la instruccin CASE de Pascal o Modula, donde se
ejecuta nicamente el cdigo correspondiente a la etiqueta en la que entramos, switch
nos da la posibilidad de ejecutar ms de una etiqueta. La sentencia break hace que al
llegar a ella salgamos directamente de switch, por tanto, poniendo break en todas las
etiquetas tendremos un comportamiento idntico al CASE. Ahora bien, si en una etiqueta
no ponemos break, el cdigo seguir hacia abajo y entrar en la siguiente etiqueta ya sin
comprobar si el valor se corresponde con la variable del encabezado porque de hecho no
lo har.
Si escribimos un switch donde ninguna etiqueta tenga break, entonces al entrar en una
se ejecutarn todas las dems que estn por debajo. Por ejemplo:
Cdigo:

switch(num){
case 1: System.out.print(1 );
case 2: System.out.print(2 );
case 3: System.out.print(3); break;
default: System.out.println(No se eligi nada entre 1 y 3.);
}

Si aqu num vale 1, entonces en la salida veremos 1 2 3 ya que entrar en la primera


etiqueta, la ejecutar y como no tiene break entrar en la segunda la cual tampoco tiene
break por lo cual entrar en la tercera que s tiene break para evitar que el flujo siga de
largo a la etiqueta default.
Podemos elegir a qu etiquetas poner break y a cules no. Asimismo el orden de las
etiqueta puede ser cualquiera, no tiene por qu ser ascendente como el del ejemplo ni
mucho menos.
Este comportamiento puede resultar til para algunos casos.

Ejercicio:
Escriban un programa que muestre un men al usuario donde pueda elegir si quiere
calcular el rea y el permetro de un tringulo, un rectngulo o una circunferencia. Si el
usuario no elije una de las opciones dadas entonces se le mostrar un mensaje de error.
Las opciones sern numricas y se leern como enteros Veamos un ejemplo:

Cita:

Bienvenido a reas y Permetros.


Seleccione una opcin:
1-- Calcular rea y permetro de un tringulo.
2-- Calcular rea y permetro de un rectngulo.
3-- Calcular rea y permetro de una circunferencia.

Seleccin: 3
Ingrese el radio de la circunferencia: 2
El rea es: 12.56
El permetro es: 12.56

Es un programa super sencillo, pero servir mucho de prctica para afianzar Java y dejar
de lado los viejos vicios arraigados de Pascal y Modula.

Precio de IGV

Cdigo:

import java.util.Scanner;

public class preciosIVA {


public static void main(String[] args){
Scanner Entrada= new Scanner(System.in);
double harina,leche,azucar,sal,arroz, porcentaje ;
final int iva=23;
System.out.print("Precio HARINA :");
harina= Entrada.nextDouble();
System.out.print("\nPrecio LECHE :");
leche= Entrada.nextDouble();
System.out.print("\nPrecio AZUCAR :");
azucar= Entrada.nextDouble();
System.out.print("\nPrecio SAL :");
sal= Entrada.nextDouble();
System.out.print("\nPrecio ARROZ :");
arroz= Entrada.nextDouble();
porcentaje=harina*iva/100;
System.out.print("\nHARINA + IVA :" + (harina+porcentaje));
porcentaje=leche*iva/100;
System.out.print("\nLECHE + IVA :" + (leche+porcentaje));
porcentaje=azucar*iva/100;
System.out.print("\nAZUCAR + IVA :" + (azucar+porcentaje));
porcentaje=sal*iva/100;
System.out.print("\nSAL + IVA :" + (sal+porcentaje));
porcentaje=arroz*iva/100;
System.out.print("\nARROZ + IVA :" + (arroz+porcentaje));
}
}
Ejercicio que tiene que ver con switch xd

Cdigo:
import java.util.Scanner;
public class AreasyPerimetros {
public static void main(String[] args){
Scanner entradaEstandar= new Scanner(System.in);
int a,b,c,altura,perimetro,opcion;
double area,per;
System.out.print("Bienvenid@ a Areas y Perimetros.\n\n" + "Elige una Opcion:\n\n"
+ "1.Un triangulo. \n2.Un rectangulo.\n3.Una circunferencia\n\n"
+ "\n\nSeleccion:" );
opcion=entradaEstandar.nextInt();

switch(opcion){
case 1: System.out.print("\n\nVamos con el area del triangulo.\nLa base sera el primer lado
ingresado \nIngresa la medida de sus lados y su altura:"
);
a= entradaEstandar.nextInt();
b= entradaEstandar.nextInt();
c= entradaEstandar.nextInt();
altura= entradaEstandar.nextInt();
entradaEstandar.nextLine();
System.out.print("\nLado a=" + a + "\nLado b=" + b + "\nLado c=" + c
+ "\nAltura=" + altura);
area= a*altura/2.0;
perimetro= a+b+c;
entradaEstandar.nextLine();
System.out.print("\nArea= "+ area + "\nPerimetro=" + perimetro); break;
case 2: System.out.print("\n\nVamos con el area y el perimetro del rectangulo."
+ "\nIngresa la medida de la base y altura: "
);
a= entradaEstandar.nextInt();
b= entradaEstandar.nextInt();
System.out.print("\n\nBase=" + a + "\nAltura=" + b);
area=a*b;
perimetro=2*(a+b);
System.out.print("\n\nArea="+ area + "\nperimetro=" + perimetro); break;
case 3: System.out.print("\n\nVamos con la circunferencia.\nIngresa la medida del radio: ");
a= entradaEstandar.nextInt();
area=a*a*3.14;
per= a*2*3.14;
System.out.print("\n\nRadio=" + a + "\n\nArea=" + area +"\nPerimetro=" + per);
break;
}

}
}

LECCIN 66: REPETICIN ITERATIVA EN JAVA TIPOS A DEFINIR.


REPETICIN ITERATIVA
Java tiene las mismas estructuras de repeticin iterativa que Pascal y Modula. Hay alguna
diferencia mnima que veremos en detalle. Tenemos entonces algo como el FOR, algo
como el WHILE y algo parecido al REPEAT. Vallamos una a una:

SECUENCIA DE REPETICIN FOR:


Como ya sabemos de sobra la sentencia for realiza una repeticin iterativa que no
depende de una condicin sino que depende de un contador. De este modo decimos que
for itera un nmero de veces predefinido, el cual puede estar dado por un valor literal,
una constante, una variable, una expresin matemtica (no recomendado), etc.
En Pascal o Modula la instruccin for utilizaba una variable de control previamente
definida la cual era inicializada en el propio encabezado del for. Por ejemplo, sea i una
variable entera:
Cdigo:

FOR i:= 1 TO n DO

La variable de control (en este caso i) deba estar definida previamente. Bien, en Java la
sentencia for tiene un encabezado ms complejo. Lo escribir de forma genrica y luego
veremos ejemplos:
Cdigo:

for ( variable ; condicin de fin ; incremento o decremento)

Veamos un ejemplo de un FOR en Modula y luego lo llevaremos a Java para que se


entienda:
Cdigo:

FOR i:= 1 TO 10 DO
WriteString(*);
END;

Estamos de acuerdo en que este FOR imprime 10 asteriscos verdad? Bien, vemoslo en
Java:
Cdigo:

for (i = 1; i<=10 ; i= i + 1)
System.out.print(*);

Como ven el encabezado del for tiene tres argumentos que se separan por punto y coma.
El primero indica la variable de control a utilizar y con qu valor se inicializa. El segundo
argumento indica la condicin de fin del for (s, el for de Java tiene condicin). El tercer
argumento indica el aumento de la variable de control o bien, el decremento de la misma.
En este caso aumentamos i en 1, pero podra haber sido 2 o ms, depende de la
necesidad.

La asignacin de acumulacin es ya bien conocida por ustedes, es decir que algo como
i= i + 1 no debera resultarles extrao. Java sabe que es usual hacer eso y por tanto nos
provee de esta forma de escribirlo:
Cdigo:

i++;

Esa instruccin aumenta i en 1, idntica a hacer


Cdigo:

i= i + 1;

Veremos ms de esto ms adelante. Lo importante es que usndolo el encabezado del for


quedara as:
Cdigo:

for (i = 1; i<=10 ; i++)

Si ustedes buscan informacin del for de Java en Google lo vern siempre de esta forma.
Como el for del ejemplo tiene una nica instruccin puedo elegir si poner llaves o no,
pero cuando tiene ms de una instruccin s o s hay que poner llaves:
Cdigo:

for (i = 1; i<=10 ; i++){


System.out.print(*);
Sistem.out.println();
}

Este for da una salida idntica al anterior.


El ltimo detalle nuevo que tenemos para el for en Java es que podemos declarar la
variable de control en el mismo for, lo cual es lo ms habitual. Quedara as:
Cdigo:

for (int i= 1; i<=10 ; i++)


System.out.print(*);

La nica restriccin para este uso es que la variable declarada dentro del for no debe
estar declarada antes, de otro modo no tendra sentido redeclararla. Asimismo, la
variable declarada en el for no ser visible fuera de l (como si fuera local), por tanto, si
se quiere usar luego s debemos declararla.

REPETICIN CONDICIONAL CON WHILE:


En Java tenemos el viejo y querido while y por suerte funciona idntico al WHILE de Pascal
y Modula. Obviamente la declaracin cambia ya que no es WHILEDO, solo es while:
Cita:

while(condicin)
instruccin;
Cita:

while(condicin){
instruccin;
}

All tienen dos ejemplos de while con una sola instruccin. Como ya debera ser natural,
en Java siempre que tenemos una sola instruccin podemos optar por no poner las llaves
de cierre y apertura al igual que en Pascal podamos optar por no poner BEGIN y END. La
forma general de un while entonces es:
Cdigo:

while (condicin){
instruccin1;
instruccin2;
...
instruccin;
}

Debera ser obvio que la condicin puede ser una condicin compuesta por operadores
NOT, AND, OR, etc. Debe estar siempre entre parntesis.
No me detendr ms con esta instruccin porque no tiene caso, es lo que ya conocen.

REPETICIN CONDICIONAL CON DOWHILE:


Como dije antes, esta sera la forma que Java le da al REPEATUNTIL que ya conocemos.
Esta instruccin igualmente difiere un poco con la de Pascal y Modula por una sutileza.
Veamos su declaracin:
Cdigo:

do{
instrucciones;
}while (condicin);

Primero vuelvo a aclarar que si hay una sola instruccin podemos omitir las llaves (no lo
recomiendo). Bien, como se darn cuenta enseguida, este bloque chequea la condicin al
final y no al inicio como while, de modo que al igual que REPEAT se ejecutar al menos
una vez. El tema es que REPEATUNTIL es como decir Repite hasta que y DOWHILE
es Haz mientras que.
Mientras que REPEAT tena la condicin inversa al WHILE, ahora en Java tanto while
como dowhile tienen la misma condicin. Veamos ejemplos sencillos:

Como acabo de decir, la condicin en Java siempre es la misma tanto para while como
para dowhile. Esto no es menor ya que de este modo la nica diferencia entre una
estructura y otra es que while puede no ejecutarse nunca y dowhile se ejecuta siempre
al menos una vez.

Ejercicio:
Realicen el programa Adivinador propuesto en Pascal pero ahora en Java. A continuacin
les dejar la letra propuesta en aquel momento, pero antes debemos ver cmo generar
nmeros aleatorios en Java. Esto ser un simple acercamiento al tema ya que Java nos
provee varias opciones a la hora de generar un nmero al azar.
Existe una clase llamada Random la cual est en el paquete java.util. Debemos
declarar un objeto de esta clase e inicializarlo para luego, a travs de l, generarnos
nmeros al azar. Veamos un ejemplo sencillo de un programa que genera nmeros
aleatorios entre el 0 y el 5:

Cdigo:

import java.util.Random;
public class Aleatorio {
public static void main(String[] args){
Random generador= new Random(); //Mi objeto de tipo Random.
int numeroAleatorio; //Mi variable para guardar el nmero generado.
numeroAleatorio= generador.nextInt(6); //Obtengo el nmero generado.
System.out.println(numeroAleatorio);
}//Fin de main.
}//Fin de Aleatorio.

Como ven tenemos una operacin de Random llamada nexInt que toma un entero como
argumento y nos devuelve otro entero entre 0 y el valor pasado menos 1 (igual que
Pascal). En este caso pas un literal entero como argumento pero bien poda ser una
variable entera.
Presten atencin a la letra que les dejar porque hay una pequea variante.

Ejemplos de ejecucin:
Ejemplo 1:
Cita:

Ingresa el nmero mximo a adivinar: 8


ERROR Ingresa un nmero mayor que 10
Ingresa el nmero mximo a adivinar: 50.
Ingresa el nmero mximo de intentos: 10
Dispones de 10 intentos para adivinar.
1)--> 98
Muy bien!!! Has adivinado!!!

Ejemplo 2:

Cita:

Ingresa el nmero mximo a adivinar: 120


Ingresa el nmero mximo de intentos: 20
Dispones de 20 intentos para adivinar.
1)--> 99
Lo siento, no has acertado.
El nmero que debes adivinar es menor.
Dispones de 19 intentos para adivinar.
2)--> 80
Lo siento, no has acertado.
El nmero que debes adivinar es mayor.
Dispones de 18 intentos para adivinar.
3)--> 85
Muy bien!!! Has adivinado!!!
Ejemplo 3:
Cita:

Ingresa el nmero mximo a adivinar: 1200


Ingresa el nmero mximo de intentos: 50
Dispones de 50 intentos para adivinar.
1)--> 60
Lo siento, no has acertado.
El nmero que debes adivinar es menor.
...
Dispones de 1 intentos para adivinar.
50)--> 13
Lo siento, no has acertado.
Lamentablemente has perdido. El nmero era 856
Pequea mejora del Adivinador:

Mejoraremos un poco el algoritmo del programa Adivinador de la siguiente manera:

El usuario puede ingresar como rango mximo cualquier nmero mayor que 10,
de lo contrario el programa le avisar como en el programa anterior.
El nmero mximo de intentos no puede ser menor que el rango mximo divido
10. Por ejemplo, si el rango mximo es 500, el nmero de intentos no puede ser
menor que 50. Si el usuario ingresa un rango menor al mnimo el programa se lo
notificar de este modo:
Cita:

Ingresa el rango mximo a adivinar: 520


Ingresa el nmero mximo de intentos: 25
ERROR Muy pocos intentos. Los intentos mximos deben ser mayores o iguales a 52.
Ingresa el nmero mximo de intentos: 52

Es un agregado sencillo que prcticamente no complica mucho la estructura que ya


tengan de su programa.

TIPOS DE DATOS DEFINIDOS POR EL PROGRAMADOR


Este es uno de los aspectos de Java en donde encontraremos ms diferencia respecto a
Pascal y Modula. En aquellos dos lenguajes tenamos los siguientes tipos a definir como
programadores:

Enumerados.
Subrangos.
Arreglos.
Registros.
Conjuntos (Set no lo utilizamos).
Punteros.

Los enumerados en Java no existan hasta hace muy poco. Su uso igualmente difiere
bastante del que les dbamos, pero lo veremos poco a poco. Igualmente, de los tipos
listados arriba, en Java solo quedan estos:

Enumerados.
Arreglos.

Cmo? Pues s, la forma en que funciona Java hace que cosas como registros, conjuntos
o subrangos no se hagan necesarias como tipo predefinido por el lenguaje, sino que
nosotros mismos con las clases podemos lograr incluso mejores resultados que con los
registros (por ejemplo). De esta manera, veremos estos dos tipos a definir para luego
pasar a la declaracin de funciones y procedimientos y as llegar a la orientacin a
objetos en Java donde empezaremos a ver realmente el potencial de este lenguaje, ya
que hasta ahora solo hemos repasado conceptos ya asimilados traducindolos a la
sintaxis de Java.

ENUMERADOS:
Como dije, los enumerados no existan en Java hasta hace poco. Esto indica que
podamos lograr sin ellos los mismos resultados que logrbamos con ellos en Pascal o
Modula. Sin embargo su existencia nos facilita muchas tareas y su uso en Java an ms.
En principio veremos un uso idntico al que ya conocemos y ms adelante, con la
Programacin Orientada a Objetos veremos ms.
En Java un enumerado se declara as:
Cdigo:

enum identificador {valor1, valor2, , valorN}

Noten que no lleva punto y coma al final de la declaracin.


El enumerado no puede estar declarado dentro de un procedimiento sino que debe ir
fuera, recomendablemente declarado al inicio de la clase. Esto es, adems de por
muchos otros motivos, porque el enumerado funcionar como si fuera un tipo de datos,
por tanto luego para trabajar con l necesitaremos declarar variables de este tipo.
Veamos un ejemplo:
Cdigo:

public class EjemploEnumerados {


enum Meses {Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio,
Agosto, Setiembre, Octubre, Noviembre, Diciembre}
public static void main(String[] args){
Meses mes= Meses.Enero;

}
}

Este programa no hace nada, solo muestra como he declarado un enumerado llamado
Meses con los meses del ao y luego, dentro del main, como he declarado una variable
del tipo Meses llamada mes a la cual he inicializado con el valor Enero. Es importante
que noten la diferencia entre el uso de los enumerados en Pascal y Modula al de Java. En
los anteriores lenguajes podamos dar a una variable de un tipo enumerado un valor de l
simplemente escribindolo, por ejemplo:
Cdigo:

Type
Meses= (Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio,
Agosto, Setiembre, Octubre, Noviembre, Diciembre);
Var
mes: Meses;
Begin
Mes:= Enero;
End;

En Java tenemos que anteponer el tipo de la variable, un punto y luego el valor a asignar
tal como ven en el ejemplo anterior:
Cdigo:

mes= Meses.Enero;

Algo nuevo e interesante es que en Pascal o Modula no podamos imprimir en pantalla


una variable de tipo enumerado directamente, sino que tenamos que, por ejemplo, usar
un CASE para imprimir su valor, algo ms o menos as:
Cdigo:

CASE mes OF
Enero: WriteString(Enero)|
Febrero: WriteString(Febrero)|
...
Diciembre: WriteString(Diciembre)|
END;

Ahora s podemos hacerlo, por ejemplo:


Cdigo:

System.out.println(mes);

Con eso saldr en pantalla el valor de la variable mes tal cual lo declaramos en el
enumerado. Hagan ustedes mismos la prueba para comprobarlo. Esto es debido a la
forma de funcionar que tiene Java, acerca de la cual iremos aprendiendo poco a poco.

USANDO UNA VARIABLE DE TIPO ENUMERADO EN UN SWITCH:

Esto es una simple aclaracin ya que no es intuitivo. Si quisiramos por algn motivo
utilizar una variable de tipo enumerado en una instruccin switch, al escribir las etiquetas
no debemos anteponer el nombre del tipo enumerado tal como lo hacemos con las

asignaciones, sino que ponemos el literal del valor como lo hacamos en Pascal y Modula.
Por ejemplo:
Cdigo:

switch(mes){
case Enero: //Algo para hacer.
break;
case Febrero: //Algo para hacer.
break;
. . .
}
En este ejemplo he puesto break, pero ya saben que no es obligatorio y qu es lo que sucede en
caso de no colocarlo.

ARREGLOS:
La palabra ARRAY ya deja de existir dentro del lenguaje. La declaracin de arreglos en
Java es bastante diferente a lo que conocemos de Pascal o Modula teniendo adems ms
de una forma de hacerlo. No hace falta declarar un tipo ARRAY ni mucho menos. Si lo que
yo quiero, por ejemplo es un arreglo de enteros simplemente me declaro una variable as:
Cdigo:

int[] miArreglo;

Con eso ya tengo un arreglo de enteros. En este caso todava no tiene ni celdas,
simplemente hemos dicho que la variable miArreglo es un arreglo de enteros. Cmo?
Pues poniendo los corchetes luego de int. Si yo quisiera declarar una variable que sea un
arreglo de nmeros reales, por ejemplo, double, lo hago as:
Cdigo:

double[] reales;

Si sacramos los corchetes seran simples variables numricas. Entonces, la declaracin


genrica de arreglos en Java es as:
Cdigo:

TipoDeDatos[] identificador;

Ahora bien cmo hacemos para decir cuntas celdas tiene el arreglo? Es fcil, por
ejemplo, quiero que el arreglo miArreglo tenga seis celdas:
Cdigo:

miArreglo= new int[6];

De forma general sera:


Cdigo:

identificador= new TipoDeDatos[cantidadDeCeldas];

La declaracin e inicializacin se puede hacer de forma conjunta como con todo en Java,
de este modo, podamos haber declarado e inicializado el arreglo de enteros miArreglo
de esta manera:

Cdigo:

int[] miArreglo= new int[6];

En la cantidad de celdas yo he puesto un literal, en este caso 6, pero podemos poner una
variable entera. Esto es algo que haban preguntado para Pascal y Mdula, es decir,
poder generar un arreglo de un tamao indeterminado inicialmente ya que estara dado
por una variable. De este modo, veamos un programa muy bsico que pida un valor al
usuario
y
genere
un
arreglo
con
esa
cantidad
de
celdas:

Cdigo:

import java.util.Scanner;
public class EjemploArreglos {
public static void main(String[] args){
Scanner entrada= new Scanner(System.in);
int cantCeldas;
int[] misNumeros;
System.out.print("Cuntos nmeros desea guardar?: ");
cantCeldas= entrada.nextInt();
misNumeros= new int[cantCeldas];
}
}

Teniendo un arreglo, se accede a sus celdas de manera idntica a Pascal y Modula:


Veamos un ejemplo sencillo con un for que inicialice las celdas de un arreglo con un
nmero al azar entre 0 y 9 y luego lo imprimimos en la salida estndar. El largo del
arreglo ser dado por una constante:
Cdigo:

import java.util.Random;
public class EjemploArreglos {
public static void main(String[] args) {
final int LARGO_ARREGLO= 10;
Random generadorAleatorio= new Random();
int[] arreglo= new int[LARGO_ARREGLO];
for(int i=0; i<LARGO_ARREGLO; i++)
arreglo[i]= generadorAleatorio.nextInt(10);
for(int i=0; i<LARGO_ARREGLO; i++)
System.out.print(arreglo[i]+" ");
}
}

Algo a destacar es que Java siempre numera las celdas de los arreglos a partir del 0.
Un cdigo muy sencillo y corto. Lanlo con tranquilidad.
Inicializacin explcita de arreglos:

Java nos provee de una forma de declarar arreglos poniendo explcitamente los valores de
sus celdas. Por ejemplo, si quiero un arreglo de tres celdas con los valores 10, 28 y 77
puedo hacer esto:
Cdigo:

int[] miArreglo= {10,28,77};

All la variable miArreglo es un simple arreglo de tres celdas. Luego podemos hacer con
l lo que queramos.
Arreglos multidimensionales:

Bien, en Java declarar un arreglo, por ejemplo, de dos dimensiones (una tabla) no tiene
ms ciencia que esto:
int [][] miTabla= new int[10][5];
Ah tenemos un arreglo de 10 filas por 5 columnas. Como ven, es solo poner tantos []
como dimensiones queramos y ya. Luego, al hacer new debemos poner los valores para
cada
dimensin
del
arreglo
y
listo.
Del mismo modo se accede a un arreglo multidimensional:
Cdigo:

miTabla[1][2]= 25;

As podemos tener arreglos de N dimensiones.

Declaracin multidimensional explcita:

Qu pasa si yo quiero tener una tabla pero inicializarla explcitamente como con un
arreglo normal? Pues Java nos permite hacerlo tranquilamente. Supongamos que
queremos un arreglo de 2x2:
Cdigo:

int[][] miTabla= {{10,5},{40,22}};

No es lo ms usual, pero se puede hacer.


Largo de un arreglo:

Los arreglos en Java son objetos propiamente dichos y, aunque an no los usamos como
tales, tienen ciertas caractersticas importantes a tener en cuenta, sobre todo si se desea
usarlo
en
funciones
y
procedimientos.
Lo nico que veremos ahora es que existe una constante llamada length que nos da el
largo de un arreglo como int. Si por ejemplo yo quiero guardarme en una variable el largo
del arreglo puedo hacerlo as:
Cdigo:

int largo= miArreglo.length;

Noten que no estamos usando una operacin, por eso no hay parntesis. Estamos
accediendo a una constante. De momento esto no est claro ya que corresponde a la
orientacin a objetos de Java. Los arreglos son objetos de una clase llamada Array. Si
ustedes la buscan con NetBeans, de todas las que aparecen debern cliquear sobre la
que est en el paquete java.lang.reflect. All tienen el cdigo fuente del funcionamiento
de los arreglos. No entendern nada por tres principales motivos:

No hemos visto orientacin a objetos en Java an.

No hemos visto la declaracin de funciones y procedimientos.


La clase Array utiliza en algunos bloques cdigo fuente que no est escrito en
Java.

NOTA: Para arreglos multidimensionales, length solo nos devolver el largo de la primera
dimensin declarada. Por ejemplo:
Cdigo:

int[][] miTabla= new int[10][50];

Con length tendremos el valor 10.


Si queremos obtener el largo de una segunda dimensin hacemos por ejemplo:
Cdigo:

miTabla[1].length

Hagan pruebas ustedes mismos. Java permite arreglos con columnas de largos diferentes.

SOLUCION1 Del Adivinador


Cdigo:
import java.util.Scanner;
import java.util.Random;
public class Adivinador {
public static void main(String[] args){
Scanner Entrada= new Scanner(System.in);
Random Generador= new Random();
int Nmax, opcion ,Imax,Nadivinar,adivinar,iactuales,irestantes,obtenido;
boolean a=true,ganado=false;
System.out.print("\n1)Jugar Ahora \n2)Salir"
+ "\n\nOpcion:");
opcion=Entrada.nextInt();
switch(opcion){
case 1: do {
if (a==false) System.out.print("\n\nERROR Ingresa un numero mayor que 10");
System.out.print("\n\nIngresa el numero maximo a adivinar:");

Nmax=Entrada.nextInt();
if (Nmax>10) a=true; else a=false;
}while(a==false);
a=true;
do{
if (a==false){ System.out.print("ERROR - muy pocos intentos."
+ " Los intentos deben ser mayor o igual que " + (Nmax/10) );}
System.out.print("\n\nIngresa el numero maximo de intentos:");
Imax=Entrada.nextInt();
if (Imax>=(Nmax/10)) a=true; else a=false;
}while(a==false);
Nadivinar= Generador.nextInt(Nmax);
System.out.print("\n\nDispones de "+ Imax + " Intentos \n
iactuales=1;
irestantes=Imax;

!!A Jugar!! ");

do{
System.out.print("\n\nDispones de "+ irestantes + "\n" + iactuales
+ ")--> ");
obtenido= Entrada.nextInt();
if(obtenido==Nadivinar){ ganado=true; irestantes=0; }else{
if (obtenido>Nadivinar) System.out.print("\nEl numero a adivinar es menor"); else{
System.out.print("\nEl numero a adivinar es mayor");
}
ganado=false; iactuales=iactuales+1; irestantes=irestantes-1;
}

} while((irestantes!=0)||(ganado=false) ) ;
if (ganado=true)System.out.print("!!HAS GANADO FELICIDADES!!"); else{
System.out.print("Has perdido , el numero era "+ Nadivinar);
}
break;
case 2: break;
default: System.out.print("Has introducido una opcion incorrecta");
}
}

SOLUCION2 ADIVINADOR
Cdigo:
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.

package adivinador;
import java.util.Random;
import java.util.Scanner;
public class Adivinador {
public static void main(String[] args) {
Random generador= new Random();//Creo el objeto Random
Scanner entradaEstandar= new Scanner(System.in); //Creo el objeto de entrada
por teclado

11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.

int maxRango, maxIntentos, num, numeroAleatorio, contador=1;


do{
System.out.println("Ingresa el rango maximo a ingresar: ");
maxRango= entradaEstandar.nextInt();
if(maxRango<10)
System.out.println("ERROR! Ingresa un numero mayor o igual que 10");
}while (maxRango <10);
numeroAleatorio= generador.nextInt(maxRango);
do{

System.out.println("Ingresa el numero maximo de intentos: ");


maxIntentos= entradaEstandar.nextInt();
if(maxIntentos < maxRango/10){
System.out.println("ERROR Muy pocos intentos. Los intentos mximos
deben ser mayores o iguales a " + maxRango/10);
28.
}
29.
}while (maxIntentos < maxRango/10);
30.
31.
entradaEstandar.nextLine(); //Salto de linea
32.
33.
do{
34.
System.out.println("Dispones de "+maxIntentos +" intentos para
adivinar.");
35.
System.out.println(contador+")--> ");
36.
num= entradaEstandar.nextInt();
37.
System.out.println(num);
38.
if(num != numeroAleatorio){
39.
System.out.println("Lo siento no has acertado.");
40.
if(num < numeroAleatorio)
41.
System.out.println("El nmero que debes adivinar es mayor.");
42.
43.
else if(num > numeroAleatorio)
44.
System.out.println("El nmero que debes adivinar es menor.");
45.
maxIntentos=maxIntentos -1;
46.
contador++;
47.
}
48.
else if(num==numeroAleatorio)
49.
System.out.println("Muy bien!! Has adivinado!!");
50.
51.
}while (num != numeroAleatorio && maxIntentos > 0);
52.
53.
if (maxIntentos==0)
54.
System.out.println("Lamentablemente has perdido. El nmero era
"+numeroAleatorio);
55.
56.
57.
}
58. }
59.
60.

LECCIN
67:
OPERACIONES
INTRODUCCIN A LA POO.

EN

JAVA

La mejor manera, segn mi criterio, de introducir las operaciones en Java es creando


algn tipo de objeto que las utilice. Esto es porque si lo hago directamente sobre la clase
principal, tendramos que usar el modificador static para crear operaciones utilizables en
el mtodo main, pero es difcil entender eso del static si an no se han creado objetos.
As que vayamos a ello.
Haremos lo siguiente:

Crearemos un nuevo proyecto llamado DatosPersonas. Crearemos una clase principal


llamada tambin DatosPersonas la cual tendr por supuesto el procedimiento main.
Luego crearemos otra clase llamada Persona que definir los objetos del tipo Persona.
Trabajaremos sobre dicha clase hasta aprender todos los conceptos necesarios para que
quede idntica al mdulo Persona de nuestro pequeo sistema en Modula 2 al cual
habamos llamado NominaPersonas.
Bien, comencemos poco a poco:

Creamos el nuevo proyecto tal como hemos hecho hasta ahora.


Creamos una clase y la llamamos DatosPersona. Su cdigo fuente ser el
mnimo indispensable para que sea reconocida como clase principal, es decir

Cdigo:

1. public class DatosPersonas {


2.

public static void main(String[] args){

3.
4.

5. }

Creamos una clase llamada Persona. Su cdigo fuente ser simplemente este:

Cdigo:

6. public class Persona{


7.
8. }

Es decir que solo est declarada como clase pblica y nada ms. Recuerden que para
declarar una clase simplemente va la palabra class, luego el identificador y las llaves de
apertura { y cierre } que forman el cuerpo de la clase. En este caso agregamos adems
el modificador public para que la clase sea accesible desde otros mdulos del programa .
En Modula tenamos aquello de archivo de definicin y archivo de implementacin. Como
dije antes, en Java todo est en el mismo archivo, es decir, en la clase. Las clases definen
por s mismas tipos de objetos que podemos crear con ellas. De este modo, al definir una
clase Persona, ya estamos definiendo una futura creacin de objetos de tipo Persona.
En Modula tenamos que definir en el archivo de definicin que bamos a usar un tipo de
objetos de ese mdulo. Eso lo hacamos con los tipos opacos. Ahora olvidamos ese
aspecto porque la propia declaracin de la clase define que se crearn objetos de ese
tipo.
Luego, en Mdula debamos ir al archivo de implementacin y dar una representacin
para el tipo de objetos que bamos a crear. Esto lo hacamos con un puntero a un registro
que definamos en el mismo mdulo. Por ejemplo, el tipo Persona del sistema
NominaPersonas era as:

Cdigo:

1. TYPE
2. Persona= POINTER TO DatosPersona
3.
4. DatosPersona= RECORD
5.

Nombre, Apellido: TipoNombre;

6.

Edad, Documento: CARDINAL;

7.

SueldoPorHora: REAL;

8.

HorasTrabajadas: REAL;

9. END;
10.

Antes dije que en Java no podemos manejar punteros y tambin dije que no tenemos
registros. As que esa definicin de arriba solo nos servir como modelo. Tomemos de ese
tipo simplemente los datos Nombre y Apellido, es decir, de momento nuestros objetos
Persona tendrn solo un nombre y un apellido. Cmo definimos eso en Java? Pues fcil,
declaramos dos variables para esos datos y ya:
Cdigo:

1. public class Persona {


2.

public String nombre;

3.

public String apellido;

4. }

Como ven solo declare dos variables del tipo String, pero qu es eso de public en las
variables?
Esa palabra la han visto ya al declarar la clase. Se trata de un modificador de acceso;
en este caso quiere decir que esas variables son pblicas de la clase Persona, es decir,
podemos acceder a ellas desde otra clase cualquiera. Es casi como si fueran variables
declaradas en el DEF de un mdulo de Modula 2. Vamos un ejemplo:
Ya tenemos entonces nuestra clase Persona declarada la cual tiene dos variables
pblicas para almacenar un nombre y un apellido. Vamos entonces a la clase principal y
nos declaramos una variable llamada p del tipo Persona:

Cdigo:

1. public class DatosPersonas {


2.

public static void main(String[] args){

3.

Persona p;

4.
5.

6. }

Sabiendo ustedes que p entonces ser un objeto de tipo Persona, deberan ya deducir
entonces que p en realidad es una referencia a un objeto de tipo Persona. La variable p
contendr la direccin de memoria en donde estar el objeto Persona con su nombre y su
apellido.
Ahora p est simplemente declarada por lo cual no sabemos qu valor posee, incluso si
quisiramos usarla ahora NetBeans no dara un error de sintaxis porque la variable no
est inicializada.
Cmo la inicializo? Pues en Modula tenamos una operacin constructora llamada
CrearPersona, la cual se encargaba de solicitar memoria y apuntar al puntero a dicho
lugar de memoria. Esta operacin adems se encargaba de asignar los valores de los
atributos ya que los reciba como argumentos. Recordmosla:
Cdigo:

1. PROCEDURE CrearPersona(documento: INTEGER; nombre, apellido:


TipoNombre; edad: INTEGER; sueldo, horas: REAL): Persona;

En Java tambin necesitamos una operacin constructora, sin embargo, como no la


hemos definido Java nos da una por defecto la cual recibe el mismo nombre de la clase y
no requiere argumentos. Las operaciones constructoras en Java siempre se usan
mediante el operador new. De este modo, para inicializar la variable p hacemos
Cdigo:

1. p= new Persona();

El operador new, al igual que en Pascal y Modula solicita memoria para almacenar un
objeto y la reserva. Mediante la operacin constructora se encarga, luego de haber
pedido memoria, de inicializar los atributos del objeto retornando finalmente la direccin
de memoria hacia l. A nosotros no nos importa la direccin de memoria ni cmo se
escribe, nos importa que p es una referencia a un objeto y ya; o sea, seguiremos viendo a

p como una flecha hacia una entidad de memoria que contiene muchos datos
manipulables.
Cmo sabe la operacin constructora cmo inicializar los atributos del objeto?
Seguramente ahora eso de una operacin constructora por defecto suena raro. Pues bien,
como no hemos escrito nada sobre esta operacin, sino que nos apegamos a la que Java
nos da, debemos saber que los atributos se inicializarn entonces con valores
predeterminados:

Variables de tipos primitivos se inicializan en 0 o en FALSE si son booleanos.


Variables que son referencias a objetos se inicializan en null (lo veremos luego).

En este caso, nuestra clase Persona tiene solo dos atributos: nombre y apellido. Estos
atributos son del tipo String, por tanto no son tipos primitivos sino que son referencias a
objetos as que se inicializarn en null. Esto significa que son Strings nulos, lo cual no es
lo mismo que Strings vacos representados por el valor .

EL VALOR NULL:
As como yo poda definir en Pascal y Modula un puntero que no apuntara a nada
asignndole el valor NIL, en Java puedo hacerlo tambin. Sabiendo que las referencias a
objetos son punteros a esos objetos, puedo asignar a un puntero el valor NIL, solo que en
Java se llama null. Por tanto yo puedo hacer algo como esto :
Cdigo:

1. p= null;

Como null es un valor aplicable a cualquier variable puntero, es decir, a cualquier


referencia a objetos, puedo preguntar sobre su valor comparando:

Cdigo:

1. if (p==null)
2.

. . .

Esto es igual que en Pascal y Modula.

ACCEDIENDO A ATRIBUTOS PBLICOS:


Bien, continuando con el ejemplo, tenemos en nuestra clase principal un objeto p del tipo
Persona el cual sabemos fue inicializado con valores por defecto de modo que sus
nicos dos atributos son nulos.
Completemos el ejemplo asignando un nombre y un apellido al objeto p accediendo
directamente a su representacin para luego imprimir eso en la salida estndar. Veamos
el cdigo fuente de la clase principal completo:
Cdigo:

1. public class DatosPersonas {

2.

public static void main(String[] args){

3.

Persona p= new Persona();

4.
5.

p.nombre= "Kyshuo";

6.

p.apellido= "Ayame";

7.
8.

System.out.println("Nombre: " + p.nombre + "\nApellido: "


+ p.apellido);

9.

10. }

Como pueden ver, para acceder a las variables del objeto simplemente ponemos el
nombre de la referencia, un punto y luego el nombre de la variable. Es ms, si ustedes
escriben el nombre de la referencia al objeto de tipo Persona y un punto vern que
NetBeans despliega un listado de lo que tenemos disponible. All vern las variables que
definimos y luego alguna otra cosa ms que de momento no sabemos de dnde sale. Ya
investigaremos sobre el tema.
Si al escribir una referencia a un objeto seguida de un punto no ven el listado de opciones
o bien, NetBeans lo cerr, simplemente presionen ALT Gr + ESPACIO y lo tendrn a su
disposicin. Resulta muy til, sobre todo cuando tengamos muchas clases con muchas
variables y dems.
De este modo hemos accedido directamente a las variables (atributos) de la clase
Persona. Esto nicamente fue posible porque estas variables fueron declaradas como
pblicas y por tanto podemos acceder a ellas desde otra clase que no sea la clase
Persona.

MODIFICADOR DE ACCESO PRIVATE Y OPERACIONES EN JAVA:


Lo que hicimos entonces fue definir una clase Persona que declara nicamente dos
atributos: nombre y apellido. Estos atributos fueron declarados como pblicos y por tanto
desde la clase DatosPersonas pudimos acceder a ellos mediante un objeto de la clase
Persona referenciado por una variable p. A estas alturas del partido ustedes deberan
estar de acuerdo conmigo en que dejar que los usuarios de una clase accedan
directamente a sus atributos (representacin) de los datos no es la mejor opcin. Qu
pasa si a m se me ocurre otra implementacin para la clase Persona donde nombre y
apellido ya no sean dos variables distintas del tipo String? Veamos un ejemplo :
Cdigo:

1. public class Persona {

2.

public String[] nomApell= new String[2];

3.
4. }

Ahora ya no tenemos dos variables String sino que tenemos un arreglo de Strings de dos
celdas. La primera celda contendr el nombre y la segunda contendr el apellido. Si un
usuario pretende utilizar mi nueva clase Persona tendr que, adems de sustituir su
antigua clase Persona, modificar el cdigo fuente de su clase principal porque ya no hay
una variable nombre y una variable apellido. Si ustedes cambian el cdigo fuente en sus
PCs y compilan vern que NetBeans les marcar muchos errores.
Para solucionarlos pueden, o bien dejar la clase Persona como estaba, o bien modificar la
clase principal. En este caso no sera un trabajo arduo, pero en un sistema grande ya
pueden imaginar que s.
Esto muestra en un ejemplo prctico que declarar los atributos de una clase como
pblicos hace que se pierda individualidad en el cdigo, de modo que un cambio en una
clase impacta directamente sobre el cdigo fuente de otras. Esto no es para nada lo que
queremos. Por eso ya Modula ocultaba la representacin del tipo de objetos que
implementbamos y nos valamos de las operaciones para manipular la informacin.
Volvamos entonces a tener nuestro atributo nombre y nuestro atributo apellido pero
ahora declarados como private y no como public:
Cdigo:

1. public class Persona {


2.

private String nombre;

3.

private String apellido;

4.
5. }

Podemos declarar ambas variables en una sola lnea as verdad?


Cdigo:

1. private String nombre, apellido;


NetBeans nos marcar errores an porque ahora no podemos acceder a estos atributos
desde fuera de la clase Persona porque son privados de ella, es decir, no son visibles
para otras clases, ni siquiera la principal. Crearemos entonces una operacin
ModificarNombrePersona y una ModificarApellidoPersona que permitan justamente
dar un nombre y un apellido a un objeto Persona.

Declaracin de operaciones:

En Java toda operacin se declara de la misma manera sin importar si es funcin o procedimiento:
Cdigo:

tipoDeRetorno identificador (argumentos)


Para el mdulo Persona tenamos una operacin ModificarNombrePersona que tena esta firma:
Cdigo:

1. PROCEDRUE ModificarNombrePersona(nombre: TipoNombre; VAR p:


Persona);

En Java sera as:


Cdigo:

1. void ModificarNombrePersona(String nom);

Esto es una operacin llamada ModificarNombrePersona que retorna algo del tipo void
y recibe como argumento algo de tipo String en un parmetro llamado nom. En Java el
tipo void es un tipo nulo, es decir que, una operacin que retorna void justamente no
retorna nada y por eso sabemos que es un procedimiento. Noten que para los parmetros
va primero el tipo y luego el identificador, tal como es para las variables.
Y qu pas con el parmetro por referencia que en Modula era justamente el objeto
Persona cuyo nombre modificaramos? Pues ya veremos que esto no es necesario en
Java, adems de que ya no existe el pasaje de parmetros por referencia.
La operacin ModificarNombrePersona quedara entonces as:
Cdigo:

1. void ModificarNombrePersona(String nom){


2.

nombre= nom;

3. }

Cmo sabe Java a qu objeto Persona modificar el nombre? Pues, qu mejor manera
que verlo con un ejemplo? Veamos, desde la clase principal, teniendo dos objetos
Persona distintos, cmo asignamos un nombre a cada uno:
Cdigo:

1. public class DatosPersonas {

2.

public static void main(String[] args){

3.

Persona p1= new Persona();//Creo un objeto Persona y lo


referencio con p1.

4.

Persona p2= new Persona();//Creo un objeto Persona y lo


referencio con p2.

5.
6.

p1.ModificarNombrePersona("Kyshuo"); //Le asigno nombre a


p1.

7.

p2.ModificarNombrePersona("Pepe"); //Le asigno nombre a


p2.

8.
9.

10. }

Como pueden observar, la operacin ModificarNombrePersona, al ser una operacin


de la clase Persona, se hace a travs de un objeto de esa clase. De este modo, al
escribir
Cdigo:

1. p1.ModificarNombrePersona(Kyshuo);

queda totalmente explcito que lo haremos con el objeto p1. Las operaciones que se hacen a travs
de un objeto de una clase siempre se realizan con esta sintaxis:

Cdigo:

1. referenciaDelObjeto.operacionARealizar(argumentos);

Al tener que, obligatoriamente, anteponer la referencia a un objeto antes del nombre de


la operacin (separados por un punto) es como si estuviramos pasando ese objeto como
argumento. Por eso no necesitamos explicitarlo como un argumento en la lista de
parmetros de la operacin como tenamos que hacer en Modula. Esto es algo propio de

Java. Para dejarlo claro, en Mdula debamos pasar por referencia un objeto del tipo en
cuestin como suceda con esta operacin
Cdigo:

1. PROCEDRUE ModificarNombrePersona(nombre: TipoNombre; VAR p:


Persona);

en Java esto ya no es as. Quitamos el parmetro objeto porque quedar explcito al


llamar a la operacin. Si en Modula tenamos un objeto de tipo Persona referenciado por
p1, debamos llamar a esa operacin as:
Cdigo:

1. ModificarNombrePersona(Kyshuo,p1);

En Java qued as:


Cdigo:

1. p1.ModificarNombrePersona(Kyshuo);
Esto traer algunas cositas interesantes a tener en cuenta de ahora en ms.

Referencia this:
En Mdula, al tener la referencia como nombre de un argumento (en la operacin
ModificarNombrePersona la habamos llamado p) nos referamos a ese parmetro para
modificar los valores necesarios. Por ejemplo, en ModificarNombrePersona hacamos:
Cdigo:

1. p^.nombre= nombre;

En Java, no tenemos un argumento explcito del tipo en cuestin. Cmo nos referimos
entonces al objeto que nos han pasado en el llamado a la operacin? Veamos esto con un
simple problema:
En el ejemplo anterior llam al argumento que pasaba el nombre de la persona nom,
pero mejor sera llamarlo nombre, de este modo la firma de la operacin
ModificarNombrePersona sera
Cdigo:

1. void ModificarNombrePersona(String nombre)

Qu pasa si dejo el cdigo anterior?


Cdigo:

1. void ModificarNombrePersona(String nombre){


2.

nombre= nombre;

3. }

Dentro de la operacin el parmetro nombre funciona como variable local, eso ustedes
ya lo tienen clarsimo. Por tanto opaca a la variable nombre global que tenemos
declarada como atributo de los objetos Persona, as que la asignacin
nombre=nombre es asignar al parmetro nombre su propio valor y por tanto la
variable global nombre queda intacta. Incluso si ustedes paran el cursor sobre la palabra
nombre que usan dentro de la operacin ModificarNombrePersona vern que
NetBeans les pinta en todo el cdigo a quin estn haciendo referencia.
Este problema no lo tenamos en Modula porque al tener el argumento p de tipo Persona
hacamos:
Cdigo:

1. p^.nombre= nombre;

Y si hacemos algo parecido en Java? Pues, como el objeto con el que hacen el llamado a
la operacin es pasado de forma implcita no tenemos un nombre con qu referenciarlo,
pero afortunadamente los creadores de Java tenan esto presente y nos dan una
referencia para el objeto en cuestin, la cual se llama this. De este modo el cdigo casi
completamente correcto de la operacin es:
Cdigo:

1. void ModificarNombrePersona(String nombre){


2.
3. }

this.nombre= nombre;

Entonces, Java nos provee SIEMPRE, queramos o no, una referencia al objeto con el que
hemos llamado a una operacin. Esta referencia se utiliza con la palabra reservada this.
De este modo, si el llamado a la operacin fue
Cdigo:

1. p1.ModificarNombrePersona(Kyshuo);

dentro de la operacin, la referencia this tendr el mismo valor que p1, es decir this y p1
sern alias. Espero que esto se entienda, porque es crucial en Java y, aunque de pronto
ahora podemos prescindir del uso de this, luego no habr manera de avanzar sin esta
referencia, por tanto les pedir que pregunten todo lo que les haga falta.
Yo creo que una buena forma de adaptarse a esto es pensar que ya no necesitamos para
nada declarar en nuestras operaciones un parmetro que sea del tipo del objeto que
estamos tratando porque Java siempre lo recibir de forma implcita y lo llamar this. Es
como si en Modula la operacin ModificarNombrePersona tuviera esta firma:
Cdigo:

1. PROCEDURE ModificarNombrePersona(nombre: TipoNombre; VAR this:


Persona);

Java entonces SIEMPRE declara por nosotros un parmetro del tipo objeto en cuestin y lo
llama this. Con eso nos ahorramos tener que pasar los objetos como argumentos de las
operaciones y adems no tenemos que declararlos ms en los encabezados de las
mismas.
No est de ms aclarar que el objeto pasado a la operacin se pasa por copia (por valor),
por eso digo que this y p1 son alias. De este modo realmente es como si en Modula la
firma fuera esta:
Cdigo:

1. PROCEDURE ModificarNombrePersona(nombre: TipoNombre; this:


Persona);

FUNCIONES EN JAVA:
Como ya dije, las operaciones en Java se declaran siempre de la misma manera sin
importar si son procedimientos o funciones:

Cdigo:

1. tipoDeRetorno Identificador (argumentos);

Ustedes ya tienen bien claro que un procedimiento no retorna nada y en cambio una
funcin s lo hace. De este modo, para declarar un procedimiento le damos el tipo de
retorno void, que justamente es el tipo nulo de Java para retornos. Claramente entonces,
si ponemos otro tipo de retorno distinto de void estamos declarando una funcin.
Veamos, ahora que nuestra clase Persona tiene sus atributos como privados, cmo
utilizar una funcin para que nos retorne el nombre. Recordmosla primero en Modula:
Cdigo:

1. PROCEDURE ObtenerNombrePersona(p: Persona): TipoNombre;


2. BEGIN
3.

RETURN p^.Nombre;

4. END ObtenerNombrePersona;

En Java ser:

Cdigo:

1. String ObtenernombrePersona(){
2.

return this.nombre;

3. }

Seguimos un poco con el tema de la referencia this. Vern que en Modula haca falta
pasar el objeto Persona como argumento pero, como ya dije, Java siempre lo pasa de
forma implcita y le llama this, por tanto no necesitamos declarar ningn argumento para
esta operacin.
Noten que es una funcin que retorna algo del tipo String, por tanto podemos usarla a la
izquierda de una asignacin, cosa que no podemos con un procedimiento.
En Java, las funciones tambin tienen una sentencia return que s o s es requerida, la
cual funciona exactamente igual que en Modula, es decir que, llegada a la sentencia
return salimos de la operacin sin importar si haba cdigo por ejecutarse debajo. Mucho
ojo con eso.
Los procedimientos, o funciones nulas como los llaman algunos (para m esa
nomenclatura es errnea), no requieren sentencia return porque justamente no retornan
nada. Sin embargo podemos poner si queremos una sentencia return vaca:

Cdigo:

1. return;
Si la usamos, NetBeans la subrayar en amarillo y nos dir que es innecesaria, sin
embargo compilar y funcionar correctamente si la dejamos ah.
No colocar al menos una sentencia return en una funcin es un error de sintaxis y
NetBeans nos lo indicar enseguida. Cuando una funcin se vuelve compleja y tiene
muchos if y bucles tendemos a tener distintas sentencias return de modo que se realizar
la una o la otra. NetBeans chequear que las condiciones aseguren que siempre habr
alguna sentencia return que se ejecutar, si no es as nos dir que hay un error de
sintaxis. Por ejemplo:
Cdigo:

1. if (X>=0) then
2.

return Mayor que cero;

3. else
4.

X= 0;

En ese caso si X es mayor o igual que 0 retornamos un String (suponiendo que ese
cdigo corresponde a una funcin de tipo String), pero si no es as le asignamos a X el
valor 0 y ya. En ese caso NetBeans detecta que hay posibilidad de llegar a un momento
en que no haya un return posible (cuando entramos en el else) y nos marcar un error. De
este modo tenemos dos opciones:

Agregamos una sentencia return en el else.


Tenemos una variable declarada especficamente para guardar el valor a retornar
y declaramos as una nica sentencia return fuera del if.

La segunda opcin es la ms recomendable, cada uno lo hace como quiera. Veamos un


ejemplo con el pequeo cdigo de arriba:
Cdigo:

1. . . .
2. String ret; //La variable para retornar algo.
3.
4. if(X>=0)
5.

ret= Mayor que 0;

6. else{

7.

X=0;

8.

ret= Asignado a 0;

9. }
10.
11. . . .
12. return ret;

OPERACIONES PBLICAS Y PRIVADAS:


Las operaciones que hemos declarado en nuestra clase Persona han sido operaciones
accesibles desde otras clases, en este caso, las accedamos desde la clase principal. Esto
implica que son operaciones pblicas de la clase Persona. En Mdula esto se
especificaba declarando las operaciones en el DEF ya que lo que all apareca justamente
era pblico y se poda usar en otros Mdulos. En Java se hace aadiendo el modificador
de acceso public antes de declarar la operacin:
Cdigo:

1. public void ModificarNombrePersona(String nombre){


2.

nombre= nombre;

3. }
4.
5. public String ObtenernombrePersona(){
6.

return this.nombre;

7. }

Por qu si nosotros no habamos puesto el modificador public en estas operaciones


podamos acceder externamente a ellas de todos modos? Pues porque si no
especificamos ningn modificador de acceso Java implcitamente aade el modificador
public, de este modo da igual ponerlo o no ponerlo, pero es una convencin de
programadores SIEMPRE aadir el modificador public para las operaciones y atributos
pblicos.
Podemos declarar operaciones como private, es decir, operaciones que no sern
accesibles desde fuera de la clase sino que sern privadas de ella. Esto es como si en
Modula declarramos una operacin en el MOD que no estuviera en el DEF. Las
operaciones privadas son declaradas cuando necesitamos hacer alguna tarea propia de la
clase que no tiene por qu ser usada fuera y en efecto, no queremos que se pueda hacer.

Vamos a hacer entonces el TAD Persona que tenamos en Modula pero ahora en Java.
Recordemos primero el archivo DEF de este TAD:
Cdigo:

1. (*****************************************************************************
*
2. Un objeto Persona estar representado por los siguientes datos:
3.
4.

DOCUMENTO

5.

NOMBRE

6.

APELLIDO

7.

EDAD

8.

SUELDO POR HORA

9.

HORAS TRABAJADAS

10. Esta interfz describe las operaciones que se pueden realizar con un objeto
del
11. tipo Persona.*)
12.
13. DEFINITION MODULE Persona;
14. CONST
15.

MAX_LARGO_NOMBRE= 50;

16. TYPE
17.

Persona; (*Es un tipo opaco.*)

18.

(*Tipo para el nombre y el apellido*)

19.

TipoNombre= ARRAY[1..MAX_LARGO_NOMBRE] OF CHAR;

20.

(************************************)

21.

(*

CONSTURCOTRAS

*)

22.

(************************************)

23.
24.

(*Crea un nuevo objeto persona a partir de los datos ingresados como


parmetros*)

25.

PROCEDURE CrearPersona(documento: INTEGER; nombre, apellido:


TipoNombre;

26.

edad: INTEGER; sueldo, horas: REAL):


Persona;

27.
28.

(************************************)

29.

(*

30.

(************************************)

SELECTORAS

*)

31.
32.

(*Retorna el documento de una persona pasada como parmetro*)

33.

PROCEDURE ObtenerDocumentoPersona(p: Persona): CARDINAL;

34.
35.

(*Retorna el nombre de una persona pasada como parmetro*)

36.

PROCEDURE ObtenerNombrePersona(p: Persona): TipoNombre;

37.
38.

(*Retorna el apellido de una persona pasada como parmetro*)

39.

PROCEDURE ObtenerApellidoPersona(p: Persona): TipoNombre;

40.
41.

(*Retorna la edad de una persona pasada como parmetro*)

42.

PROCEDURE ObtenerEdadPersona(p: Persona): CARDINAL;

43.
44.

(*Retorna el sueldo que una persona gana por hora trabajada*)

45.

PROCEDURE ObtenerSueldoPorHora(p: Persona): REAL;

46.
47.

(*Retorna la cantidad de horas trabajadas por una persona*)

48.

PROCEDURE ObtenerHorasTrabajadas(p: Persona): REAL;

49.
50.

(*Retorna el sueldo ganado por una persona segn el sueldo que gana por

51.

hora trabajada y la cantidad de horas trabajadas*)

52.

PROCEDURE CalcularSueldoGanado(p: Persona): REAL;

53.
54.

(************************************)

55.

(*

56.

(************************************)

MODIFICADORAS

*)

57.
58.
59.

(*Asigna un nuevo documento a la persona pasada como parmetro*)


PROCEDURE ModificarDocumentoPersona(documento: CARDINAL; VAR p:
Persona);

60.
61.

(*Asigna un nuevo nombre a la persona pasada como parmetro*)

62.

PROCEDURE ModificarNombrePersona(nombre: TipoNombre; VAR p:


Persona);

63.
64.

(*Asigna un nuevo apellido a la persona pasada como parmetro*)

65.

PROCEDURE ModificarApellidoPersona(apellido: TipoNombre; VAR p:


Persona);

66.
67.

(*Asigna una nueva edad a la persona pasada como parmetro*)

68.

PROCEDURE ModificarEdadPersona(edad: CARDINAL; VAR p: Persona);

69.
70.

(*Asigna un nuevo sueldo a ganar por hora trabajada para la persona

71.

pasada como parmetro*)

72.

PROCEDURE ModificarSueldoPorHora(sueldo: REAL; VAR p: Persona);

73.

(*Asigna una cantidad de horas trabajadas para la persona pasada ocmo


parmetro*)

74.

PROCEDURE ModificarHorasTrabajadas(horas: REAL; VAR p: Persona);

75.
76.

(************************************)

77.

(*

78.

(************************************)

INFORMACIN

*)

79.
80.

(*Imprime los datos de p en el siguiente formato:

81.

Documento: ValorDelDocumento

82.

Nombre: NombrePersona

83.

Apellido: ApellidoPersona

84.

Edad: EdadPersona

85.

Sueldo por hora: ValorDelSueldo

86.

Horas trabajadas: CantidadDeHorasTrabajadas*)

87.

PROCEDURE ImprimirPersona(p: Persona);

88.
89.

(************************************)

90.

(*

91.

(************************************)

DESTRUCTORAS

*)

92.
93.

(*Liebera la memoria ocupada por p*)

94.

PROCEDURE DestruirPersona(VAR p: Persona);

95. END Persona.


Como primera observacin interesante hay que destacar que el constructor que tenamos
en este TAD no lo hemos construido an en Java y pues, no he hablado mucho de los
constructores de este lenguaje, as que vayamos a ello.

CONSTRUCTORES EN JAVA:
Hasta ahora solo sabemos que Java nos provee un constructor por defecto el cual posee
el mismo nombre de la clase en cuestin y no recibe argumentos. Nosotros, sin tan
siquiera declararlo en la clase podemos invocarlo para solicitar memoria y crear el nuevo
objeto. El hecho es que este constructor inicializa todos los atributos con un valor por
defecto lo cual ya expliqu. Y si no quiero que los atributos se inicialicen por defecto sino
que yo quiero darles un valor o hacer tareas en la construccin del objeto? Y si quiero
pasar argumentos al constructor para directamente construir un objeto con datos
definidos
u
obtenidos
de
alguna
parte?
El constructor que tenamos en Modula reciba todos los datos necesarios para dar
valores a todos los atributos del TAD Persona, a esto se le conoce como constructor
completo. Sin embargo podramos haber definido algn constructor con menos
argumentos, por ejemplo, solo con el nombre y el apellido, dejando lo dems a la deriva
de una inicializacin predefinida.
En este ejemplo concreto no tiene mucho sentido hacer tareas en el constructor por
defecto, pero a medida que los sistemas a desarrollar se vuelven complejos la forma de
inicializar un objeto al crearlo se complicar. Java nos permite entonces:

Crear nuestro propio constructor por defecto (en realidad es sobreescribir el


constructor por defecto de Java, pero lo veremos cuando lleguemos a la Herencia).
Crear tantos constructores como necesitemos.

Para inicializar los atributos de un objeto con un valor por defecto a nuestro gusto
tenemos dos opciones:

Asignamos dichos valores ya al definir los atributos.


Asignamos dichos valores dentro del constructor.

La primera forma sera como muestro a continuacin, suponiendo que el cdigo fuente de
la clase Persona es este:
Cdigo:

1. public class Persona {


2.

private String nombre= "ninguno";

3.

private String apellido= "ninguno";

4.
5.

public void ModificarNombrePersona(String nombre){

6.
7.

this.nombre= nombre;
}

8.
9.

public String ObtenernombrePersona(){

10.

return this.nombre;

11.

12. }
Como ven, los atributos estn inicializados ya en la declaracin. Podemos tambin
declarar eso mismo en una sola lnea. Lo he hecho por separado para que todo se
visualice lo mejor posible.
Ahora escribamos el constructor por defecto y demos los valores all:
Cdigo:

1. public class Persona {


2.

private String nombre;

3.

private String apellido;

4.
5.

public Persona(){

6.

this.nombre= "ninguno";

7.

this.apellido= "ninguno";

8.

9.
10.

public void ModificarNombrePersona(String nombre){

11.
12.

this.nombre= nombre;
}

13.
14.

public String ObtenernombrePersona(){

15.
16.

return this.nombre;
}

17. }
Agregamos a la clase entonces una nueva operacin. Esta operacin es extraa por dos
cosas:

Tiene el mismo nombre de la clase.


No tiene ningn tipo de retorno, ni siquiera void.

Los constructores de Java tienen reglas bien especficas las cuales son justamente las de
arriba:
[*]Deben llevar el mismo nombre de la clase a la que pertenecen.
[*]No deben tener ningn tipo de retorno asociado, ni siquiera void.
Un constructor en Java, que no recibe argumento ninguno, es justamente el constructor
por defecto. Si nosotros declaramos, como hice ahora, un constructor sin argumentos nos
estamos definiendo nuestro propio constructor por defecto. Cuando desde fuera se hace,
por ejemplo:
Cdigo:

1. p1= new Persona();


estamos justamente llamando a una operacin. La diferencia entre los llamados
habituales y uno de construccin de un objeto es que estos ltimos se hacen mediante el
operador new y a la izquierda de una asignacin a una referencia. As que como ven,
luego de new va el constructor que queremos invocar.
El tipo Persona en Modula era, como ya habamos recordado anteriormente:
Cdigo:

1. TYPE
2.

Persona= POINTER TO DatosPersona;

3.
4.

DatosPersona= RECORD

5.

Nombre, Apellido: TipoNombre;

6.

Edad, Documento: CARDINAL;

7.

SueldoPorHora: REAL;

8.

HorasTrabajadas: REAL;

9.

END;

Declaremos entonces el resto de los atributos en nuestro TAD Persona de Java, tras lo
cual completaremos el cdigo del constructor por defecto para inicializar todos los valores
de manera correcta y declararemos adems un constructor completo. Hasta ahora la
clase Persona es esta:
Cdigo:

1. public class Persona {


2.

private String nombre, apellido;

3.

private int edad, documento;

4.

double sueldoPorHora, horasTrabajadas;

5.
6.

public Persona(){

7.

this.nombre= "ninguno";

8.

this.apellido= "ninguno";

9.

10.
11.

public Persona(String nombre, String apellido, int edad, int


documento,

12.

double sueldoPorHora, double horasTrabajadas){

13.

this.nombre= nombre;

14.

this.apellido= apellido;

15.

this.edad= edad;

16.

this.documento= documento;

17.

this.sueldoPorHora= sueldoPorHora;

18.

this.horasTrabajadas= horasTrabajadas;

19.

20.
21.

public void ModificarNombrePersona(String nombre){

22.
23.

this.nombre= nombre;
}

24.
25.

public String ObtenernombrePersona(){

26.
27.

return this.nombre;
}

28. }
Bien, tenemos entonces dos constructores, es decir, dos operaciones constructoras. Algo
que tal vez a ustedes les llame mucho la atencin es que tenemos dos operaciones con el
mismo nombre. Esto es algo nuevo y se conoce como Polimorfismo, es decir, una
misma operacin puede tener muchas formas. En este caso tenemos el constructor
Persona con dos formas diferentes. Cmo sabr Java a cual constructor estamos
llamando? Pues por la cantidad y el tipo de argumentos. Veamos un ejemplo:
Cdigo:

1. p1= new Persona();


2. p2= new Persona(Kyshuo,Ayame,23,12345678,80,30);
Est claro que para p1 hemos invocado al constructor por defecto y para p2 al
constructor completo? Java se da cuenta de cual constructor debe llamar justamente
porque uno no recibe argumentos y el otro s. Asimismo podemos tener muchos
constructores distintos siempre que el tipo y la cantidad de argumentos no coincidan a la
vez en ms de una operacin. Por ejemplo:
Cdigo:

1. public Persona(String nombre, int documento);


2.
3. public Persona(String apellido, int edad);

Claramente all tenemos dos declaraciones distintas, sin embargo ambas tienen dos
argumentos cuyos tipos coinciden. Al momento de la invocacin Java no puede saber a

qu constructor de ambos estamos queriendo llamar y pues por este motivo no nos
dejar hacer estas declaraciones. Imaginen esto:
Cdigo:

1. p3= new Persona(Ermenegildo, 52);


La referencia p3 pretende ser inicializada mediante el constructor que recibe el nombre y
la edad, sin embargo para Java es un constructor que recibe un String y luego un int y no
puede diferenciar a cul queremos invocar.
Si an as quisiramos tener esos dos constructores tendramos que variar en algo, por
ejemplo el orden de los argumentos:
Cdigo:

1. public Persona(int documento, String nombre);


2.
3. public Persona(String apellido, int edad);
Ahora s Java puede diferenciar una operacin de otra porque la primera recibe un int y
luego un String y la segunda recibe un String y luego un int.
Esto es aplicable a todas las operaciones, pero lo iremos viendo luego.
NOTA: Espero que hayan podido observar que para los argumentos de las operaciones
siempre debemos declarar primero el tipo y luego el identificador, separando todos los
argumentos con una coma. No es como suceda en Pascal y Modula donde podamos
declarar varios argumentos de un mismo tipo a la vez separando por coma y luego
usando el punto y coma para declarar argumentos de un nuevo tipo. Ahora en Java
ponemos el tipo s o s por cada argumento.
Qu pasa si yo quiero que siempre se use SOLAMENTE el constructor completo para
inicializar los objetos Persona?
Muchas veces necesitamos asegurarnos de que no se usar el constructor por defecto
para crear algn objeto de una clase que estamos desarrollando ya que necesitamos ms
informacin explcitamente para lograr un buen funcionamiento. Una forma bien fcil de
lograr esto es declarar el constructor por defecto como privado, as:
Cdigo:

1. private Persona(){}
Como ven, he abierto y cerrado las llaves {}, es decir, ni siquiera puse cdigo fuente en
el cuerpo del constructor porque no lo usaremos. Podra haberlo hecho si pretendiera
usarlo internamente, pero para la clase Persona podramos querer que siempre se
inicialice con el constructor completo a fin de garantizarnos que siempre se crear un
nuevo objeto con datos sustanciales. De este modo ya tenemos esa garanta, los clientes
de mi clase no tendrn ms que usar el constructor completo.

Ejercicio:
Dado el TAD Persona que usamos en Modula 2 tal como lo he mostrado anteriormente,
reescrbanlo en Java exceptuando la operacin DestruirPersona. Esto ltimo viene a

que la destruccin de objetos en Java es muy distinta a la que conocen (lo veremos
luego).
Modifiquen el mtodo main de modo que pida al usuario un entero para la cantidad de
personas a almacenar y cree con ese valor un arreglo de personas llamado
nominaPersonas. Luego deber pedir para cada persona los datos ingresados por el
usuario e ir guardando dichas personas en el arreglo. Al final debe imprimir los datos de
todas las personas cargadas en el formato que mostrar. Veamos un ejemplo de
ejecucin donde pinto en azul la entrada ingresada por el usuario:
Cita:

Ingrese la cantidad de personas a almacenar: 3


Nombre: Mengano
Apellido: Menganoso
Edad: 20
Documento: 123456
Sueldo: 15.5
Horas: 30
Nombre: Fulano
Apellido: Fulanoso
Edad: 20
Documento: 456789
Sueldo: 15.5
Horas: 30
Nombre: Perengano
Apellido: Perenganoso
Edad: 18
Documento: 258963
Sueldo: 12.3
Horas: 10
Los datos ingresados han sido:
Mengano Menganoso, 20 aos, documento 123456, sueldo $15.5 la hora, horas trabajadas 30.
Fulano Fulanoso, 20 aos, documento 456789, sueldo $15.5 la hora, horas trabajadas 30.
Perengano Perenganoso, 18 aos, documento 258963, sueldo $12.3, horas trabajadas 10.

Este ejercicio ser una gran prctica para ustedes. Por favor, hganlo.

LECCIN 69: DESTRUCCIN DE OBJETOS EN JAVA.


En nuestra clase Persona, la cual tomamos del mdulo Persona escrito en Modula, nos
omitimos la operacin DestruirPersona. Esto se debe a que no tenemos una operacin
DISPOSE que nos permita liberar la memoria ocupada por un objeto justamente para
evitarnos el tener que preocuparnos por la memoria usada por nuestros programas. De
este modo, al menos en objetos simples como los que describe la clase Persona no tiene
sentido una operacin que los destruya, es ms, no tenemos cmo implementarla.
Cmo liberamos entonces la memoria usada por nuestros objetos? Pues en Pascal y
Modula tenamos que tener especial cuidado de no dejar colgados a nuestros objetos
porque luego quedaban inaccesibles y ocupando lugar de memoria. Esto claramente era
una mala prctica de programacin. Por ejemplo, si en Modula hacamos:
Cdigo:

1. p= CrearPersona(Kyshuo,Ayame);
2. p= CrearPersona(Mengano,Menganoso);

Claro debera ser para ustedes el error all. Primero hemos creado un objeto Persona
referenciado por p y luego hemos creado otro objeto Persona referenciado tambin por p.
Esto hace que p deje de apuntar al primer objeto creado y quede apuntando al segundo.
De este modo, el objeto con nombre Kyshuo Ayame queda perdido en memoria,
inaccesible y ocupando espacio. Lo correcto habra sido destruir el objeto Persona Kyshuo
Ayame antes de crear el nuevo, o bien, referenciar dicho objeto con otra variable.
Asimismo, suponiendo que p y q son punteros a enteros, cosas como estas estn mal:

En esos los dos primeros casos estamos dejando memoria colgada, y en el tercer caso
tenamos que p y q eran alias y luego, al disponer uno de ellos el otro queda indefinido
tambin lo cual era muy peligroso si el programador no se daba cuenta porque al intentar
acceder a un puntero indefinido tendra un error en tiempo de ejecucin.
En Java para liberar memoria justamente tenemos que dejarla colgada. !!!QU???
S, tenemos que dejar memoria colgada porque Java ser quin se encargue de liberarla
luego, nosotros no tenemos control sobre eso. De este modo, si yo hago en Java algo
como esto:
Cdigo:

1. p= new Persona(Kyshuo,Ayame);
2. p= null;
estoy dejando el objeto creado en la primera lnea colgado en memoria e inaccesible.
Justamente eso es lo que Java necesita saber para liberar esa memoria luego. O sea que,
para liberar memoria tengo que, a propsito, dejarla colgada. As, todo lo que estaba mal
en Modula y Pascal ahora en Java no nos da problemas.
Por ejemplo, el tercer caso visto recin en Modula en Java sera:
Cdigo:

1. p= new Persona(Kyshuo,Ayame);
2. q= p;
3. p= null;
All hemos dejado la referencia p en null pero no hemos afectado a q por tanto el objeto
creado no est inaccesible y por ende no est colgado en memoria.
Entonces cmo funciona realmente esto de la gestin de memoria en Java?

RECOLECCIN DE BASURA
Como estamos viendo, para liberar memoria tenemos que dejarla colgada, no tenemos
otro modo. Esto es porque en Java existe un proceso llamado Garbage Collector
(recolector de basura) que cada tanto tiempo se ejecuta y busca en memoria los objetos
que estn inaccesibles desde el programa principal liberando la memoria ocupada por
ellos, es decir, este proceso se encarga justamente de buscar y liberar todo lo que hemos
dejado colgado y que por tanto se considera basura. Entonces, el recolector de basura
elimina de memoria todo aquello que no est referenciado por nadie o bien, que no es
accesible desde el programa principal (veremos esto en detalle).
Cundo pasa el recolector de basura? Este proceso es ejecutado por la mquina virtual
de Java y nosotros como programadores no tenemos ningn control sobre l, por tanto se
ejecuta espordicamente o cuando el sistema necesita memoria para otra cosa. Nunca se
sabe entonces cuando ser ejecutado este proceso. Otro punto importante es que la
ejecucin del recolector de basura no implica necesariamente que se eliminen todos los
objetos que son considerados basura. Por tanto, si hemos dejado cinco objetos colgados,
cuando el recolector pase no tiene por qu eliminar los cinco objetos. Nosotros tampoco
tenemos
un
control
sobre
eso.
Existe una instruccin que podemos utilizar para indicar a la mquina virtual de Java que
queremos que el recolector de basura pase para limpiar la memoria la cual es:
Cdigo:

1. System.gc();

Sin embargo enfatizar especficamente la parte de que con esto indicamos a la mquina
virtual que QUEREMOS que el recolector pase, pero no implica que la mquina virtual lo
ejecute y por tanto esa decisin depender de ella. De este modo, por mucho nfasis que
pongamos en querer liberar memoria nunca sabremos efectivamente cuando ser
ejecutado el recolector de basura.
Este proceso es muy inteligente, en el siguiente sentido:

Si tenemos por ejemplo una lista encadenada y perdemos la referencia al primer


nodo estamos dejando entonces todo el contenido de la lista colgado en memoria.
En un caso as, a pesar de que cada nodo referencia al siguiente y por ende
existen objetos que son referenciados por alguien, el recolector de basura puede
determinar que en realidad no podemos llegar a ninguno de ellos desde el
programa principal.
Lo mismo sucede con una lista circular, un rbol binario, o cualquier estructura de
memoria dinmica.

Esto implica entonces que el recolector de basura puede determinar cuando toda una
enorme estructura llena de punteros que referencian a objetos de todos lados son basura
o no. Si a es una referencia a un rbol binario de bsqueda que contiene miles de nodos y
yo hago a=null, el recolector de basura podr determinar que no es posible llegar a
ningn nodo del rbol desde el programa principal y por tanto lo eliminar todo, ya no
tenemos que programarlo nosotros.
La contraparte de esto es que la recoleccin de basura es entonces un proceso muy
pesado y que consume recursos, por este motivo es la mquina virtual la que decide
cuando es necesario ejecutarlo, lo cual depender de la necesidad del sistema operativo
por usar la memoria ocupada, la carga del procesador en el momento actual (si el
procesador est muy ocupado no conviene ejecutar el recolector), la necesidad de
nuestro programa por obtener nueva memoria, etc. Toda esta complicacin queda por
parte de los programadores de Java y por tanto nosotros solo la utilizamos.

Ejemplo:

Crearemos entonces cuatro objetos de tipo Persona y luego los eliminaremos, es decir, los
desreferenciaremos con el fin de que queden como basura, inaccesibles por nosotros y
por tanto nos desentenderemos de ellos porque sabemos que Java los eliminar en algn
momento:
Cdigo:

1. public class DatosPersonas {


2.

public static void main(String[] args){

3.

Persona p1= new


Persona("Kyshuo","Ayame",23,12345678,80,30);

4.

Persona p2= new


Persona("Kyshuo","Ayame",23,12345678,80,30);

5.

Persona p3= new


Persona("Kyshuo","Ayame",23,12345678,80,30);

6.

Persona p4= new


Persona("Kyshuo","Ayame",23,12345678,80,30);

7.
8.

System.out.println(Persona.obtenerCantidadPersonas());

9.
10.

p1= null;

11.

p2= null;

12.

p3= null;

13.

p4= null;

14.

15. }

Hasta ah todo bien, sin embargo si ustedes vuelven a mostrar en pantalla el valor de la
variable cantidadPersonas vern que vuelve a salir el nmero 4. Entonces en realidad
esta variable lleva un conteo de los objetos instanciados desde el inicio del programa sin
tomar en cuenta los eliminados. De este modo si a lo largo del tiempo de ejecucin de mi
programa creo en total 1500 objetos, sea que hayan convivido en memoria todos a la vez

o no, la variable marcar el valor 1500; ms claramente, suma 1 cada vez que creamos
un objetos, jams disminuye.
Cmo hacemos para restar 1 a la variable cuando se destruya un objeto? Deberamos
saber cuando el recolector de basura elimina efectivamente a un objeto en memoria que
es considerado basura. Cmo logramos esto? Pues Java nos provee de una operacin ya
definida que se ejecuta cuando un objeto va a ser eliminado, es decir, cuando el
recolector de basura va a reclamar la memoria ocupada por un objeto que es basura este
tiene la posibilidad de ejecutar una ltima operacin antes de ser borrado. Esta operacin
se conoce con el nombre finalize.
La razn de la existencia de esta operacin es darle al programador la posibilidad de
liberar algn posible recurso que el objeto pueda estar usando antes de ser eliminado con
el fin de tener una buena gestin sobre ese recurso; un ejemplo podra ser la conexin
con una base de datos que debera ser cerrada antes de eliminar al objeto que la
representa. En este caso puntual nosotros usaremos la operacin finalize para restar 1 a
la variable cantidadPersonas a fin de que represente realmente la cantidad de objetos
de la clase Persona que existen en memoria en un momento dado.
La declaracin de la operacin finalize es:

Cdigo:

1. public void finalize()

Entonces vallamos a nuestra clase Persona y declaremos esta operacin dndole adems
un mtodo como el que muestro ahora:
Cdigo:

1. public void finalize(){


2.

Persona.cantidadPersonas--;

3. }

Vern que NetBeans les subrayar en amarillo a esta operacin. En unos momentos
veremos por qu. Vallamos ahora a la clase principal de DatosPersonas y agreguemos
estas dos lneas a lo que ya tenamos:
Cdigo:

1. System.gc();
2.
3. System.out.println(Objetos en memoria
+Persona.obtenerCantidadPersonas());

Qu hicimos? Pues agregamos un llamado al recolector de basura para intentar que el


sistema lo ejecute. Luego mostramos en pantalla cuantos objetos quedan efectivamente
en memoria luego del llamado. Ejecuten el programa varias veces y vern que el
resultado puede variar. Eso depender de si realmente el recolector de basura fue
ejecutado y adems, en caso afirmativo, depender de si fueron eliminados todos los
objetos basura. Por ejemplo, a m me sali que luego del llamado an permanecan en
memoria los cuatro objetos creados, pero tras varias ejecuciones result que siempre se
eliminaban
todos
los
objetos.
Hagan
ustedes
sus
propias
pruebas.
Tengan en cuenta que la variable cantidadPersonas indicar entonces la cantidad de
objetos de tipo Persona que existan en memoria en un momento dado, sea que nosotros
tengamos referencias a ellos o no. No es lo mismo que llevar un registro de la cantidad de
objetos Persona que nosotros tenemos referenciados.
NOTAS:

A estas alturas, y ms an si alguno de ustedes ha intentado hacer sus propios


programas en Java, habrn visto alguna sugerencia de NetBeans aunque puede que
no se hayan dado cuenta de ello. En general, NetBeans subraya en amarillo las lneas
de cdigo en las que tiene algo que comentarnos agregando adems una lamparita
en el nmero que indica la lnea en cuestin, tal como en la imagen que sigue

All ven que tenemos subrayada la palabra finalize y adems vemos la lamparita que
est en lugar del nmero 130. Si hacemos clic en la lamparita veremos que NetBeans
nos da opciones acerca de la sugerencia. En este caso particular tendremos tres:

Aadir anotacin @Override.


Aadir super.finalize().
Configurar finalize declarado Hint.

Si hacemos clic en alguna veremos que NetBeans aadir algn cdigo o nos abrir
algn cuadro de dilogo.
Mas all de eso, las sugerencias son sugerencias y si no las aceptamos todo
funcionar.

Anotacin @Override: Las anotaciones, dicho muy superficialmente, son


palabras que indican al compilador algn dato importante. Estas palabras siempre
estn precedidas por el smbolo @. En este caso particular, si ustedes presionan la
sugerencia de la anotacin vern que NetBeans agregar @Override antes de la
declaracin del procedimiento finalize. Adems marcar con un smbolo verde la

lnea en que hemos escrito la anotacin:

Esta anotacin indica al compilador que estamos redefiniendo una operacin


heredada de otra clase, en este caso, finlize lo estamos heredando de una clase
que se llama Object, sin embargo todo eso lo veremos ms adelante.

Aadir super.finlize(): Esta sugerencia tambin tiene un vnculo estricto con lo


que tiene que ver con herencia y por tanto de momento la omitiremos ya que
adems introduce manejo de excepciones, cosa que an ni he mencionado.
La tercera sugerencia no nos interesa.
Si vamos al men Ver --> Toolbars --> Memoria nos aparecer esto en la barra
de
herramientas
de
NetBeans:

Es un indicador de la memoria RAM ocupada por NetBeans y lo que nosotros


hayamos creado. Si hacemos clic en este indicador NetBeans har un llamado al
recolector de basura y tal vez libere algo de memoria, lo cual se ver reflejado en
el indicador.
A pesar de que nuestro procedimiento finalize est declarado como pblico no es
recomendable que sea invocado a propsito por un cliente de nuestra clase ya
que hara decrementar la variable cantdiadPersonas an cuando el objeto no
haya sido eliminado por el garbage collector. Incluso si nosotros lo hacemos
NetBeans nos avisar con una sugerencia de que estamos invocando a finalize
explcitamente y nos invitar a configurar dicho llamado. No nos interesa eso
porque en Java todo el mundo sabe que no se debe invocar explcitamente al
mtodo de finalize porque esto corresponde al recolector de basura.

http://www.foro.lospillaos.es/curso-gratuito-de-programacion-aprende-desde-0vt7888.html

Vous aimerez peut-être aussi