0% encontró este documento útil (0 votos)
3 vistas127 páginas

Curso Java

El documento es un curso de programación en Java diseñado para programadores con conocimientos previos en programación y programación orientada a objetos. Se abordan los fundamentos del lenguaje, sus características, y se presentan módulos que incluyen estructuras de control, programación orientada a objetos, manejo de excepciones, y desarrollo de interfaces gráficas, entre otros. El curso enfatiza la multiplataforma, seguridad y facilidad de aprendizaje de Java, destacando su utilidad en aplicaciones web y móviles.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
3 vistas127 páginas

Curso Java

El documento es un curso de programación en Java diseñado para programadores con conocimientos previos en programación y programación orientada a objetos. Se abordan los fundamentos del lenguaje, sus características, y se presentan módulos que incluyen estructuras de control, programación orientada a objetos, manejo de excepciones, y desarrollo de interfaces gráficas, entre otros. El curso enfatiza la multiplataforma, seguridad y facilidad de aprendizaje de Java, destacando su utilidad en aplicaciones web y móviles.
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

Dirección de Operación

Centro Nacional de Capacitación Sureste

PROGRAMACIÓN EN
JAVA
Dirección de Operación
Centro Nacional de Capacitación Sureste

INDICE

OBJETIVOS GENERALES 1
INTRODUCCIÓN 1
Módulo 1: Fundamentos y Características del lenguaje Java 2
Objetivo 2
Introducción 2
Java frente a los demás lenguajes 3
Java 2 Standard Development Kit 3
Mecanismos de seguridad 4
Indiferente a la arquitectura 5
Tipos de Datos, Identificadores e Instrucciones 6
Tipos de Datos 7
Identificadores 8
Palabras clave 8
Expresiones y Operadores 9
Módulo 2. Estructuras de Flujo y Control de Datos 12
Objetivo 12
Introducción 12
Estructuras de Control de Flujo 13
Instrucciones de Estructura de Datos y Bucles 14
Laboratorio Modulo 2. Estructuras de Control y Flujo de Datos 16
Módulo 3. Programación Orientada a Objetos 17
Objetivos 17
Introducción 17
Clases y objetos 17
Mensajes y métodos 18
Encapsulamiento 19
Herencia 19
Superclase y Subclases 20
Polimorfismo 20
Abstracción 20
Módulo 4. Trabajando con Clases y Objetos en Java 22

Programacion Java Página 2


Dirección de Operación
Centro Nacional de Capacitación Sureste

Objetivo 22
Introducción 22
Definición de clases 22
Constructores y creación de objetos 24
Variables y métodos de clase 27
Heredando clases en Java 31
Sobrecarga de métodos y de constructores 32
Sobreescritura de métodos 34
Clases abstractas 35
Control de acceso a miembros de una clase 35
Interfaces 36
Laboratorio Modulo 4. Clases y Objetos en Java 38
Módulo 5. Manejo de Excepciones y Recolección de Basura (Garbage Collector) 39
Objetivo 39
Introducción 39
Excepciones 39
Try...Catch...finally 40
Clase Exception 41
Capturar excepciones 41
Excepciones Predefinidas 42
Generar Excepciones 44
El Recolector de Basura ( Garbage Collector) 45
Laboratorio Modulo 5. Gestión de Excepciones 48
Módulo 6. Implementación de Objetos del Paquete Java Lang 49
Objetivo 49
Introducción 49
Clases del paquete [Link] 49
Interfaces 49
Clases 50
Boolean 50
Double 51
Float 51
Integer 51
Math 51

Programacion Java Página 3


Dirección de Operación
Centro Nacional de Capacitación Sureste

String 51
Concepto de inmutabilidad 51
Stringbuffer 52
System 52
Excepciones 52
Modulo 7. GUI de Java 54
Objetivo 54
Introducción 54
AWT Y SWING 54
Frames 54
Manejo de Eventos 55
Cómo Implementar un Manejador de Eventos 55
Reglas Generales del Uso de Componentes 57
Crear y configurar un Frame 58
Ejemplos Varios de Aplicacion de elementos de SWING 60
Laboratorio Modulo 7. GUI de Java 66
Módulo 8. Paquete [Link] 67
Objetivo 67
Introducción 67
Flujos de entrada y salida 67
Lectura y Escritura 68
Entrada y Salida estándar 69
[Link] 69
Manejo de Archivos 70
Ejemplo con File 71
Flujos (Streams) 72
Archivos de Acceso Aleatorio 74
Filtros 74
Clases que trabajan con caracteres 75
Serializacion de objetos 75
Laboratorio Modulo 8. Usando la librería [Link] 78
Módulo 9. Programación Multithreaded 79
Objetivo 79
Introducción 79

Programacion Java Página 4


Dirección de Operación
Centro Nacional de Capacitación Sureste

Hilos 79
Programas de flujo único 80
Programas de flujo múltiple 80
La clase Thread 82
Creación de un Thread 84
Manipulación de un Thread 88
Suspensión de un Thread 89
Parada de un Thread 89
Grupo de Hilos 90
Suspender y Reanudar Threads 91
Estados de un Threat ( sincronización 92
Nuevo Thread 92
Laboratorio Modulo 9. Uso de Hilos en Java 96
Modulo 10. JDBC 97
Objetivo 97
Introducción 97
El driver con la base de datos 97
Conectarnos con la base de datos 98
Creamos la tabla en Base de Datos ... y la borramos. 99
Insertar datos en la base de datos 100
Consultar datos de la base de datos 100
Update en la base de datos 101
Borrar datos de la base de datos 101
Cerrar conexiones 102
Laboratorio Modulo 10. JDBC 103
Conclusion 104
APENDICE . RESOLUCION DE LABORATORIOS 105
Respuesta Laboratorio Modulo 2. Estructuras de Flujo y Control de Datos 106
Respuesta Laboratorio Modulo 4. Clases y Métodos 108
Respuesta Laboratorio Modulo 5. Gestión de Excepciones 110
Respuesta Laboratorio Modulo 7. GUI de Java 111
Respuestas Laboratorio 8. Uso de la librería [Link] 117
Respuesta Laboratorio 9. Programación MultiThread 119
Respuestas Laboratorio 10. JDBC 121

Programacion Java Página 5


Dirección de Operación
Centro Nacional de Capacitación Sureste

OBJETIVOS GENERALES

Este curso está diseñado para programadores con conocimientos suficientes de metodología de la
programación y/o Programación Orientada a Objetos que deseen introducirse en este lenguaje
multiplataforma con el que se pueden realizar las más diversas aplicaciones, tanto para PC como para
Internet o dispositivos móviles , ya que la plataforma para dichas tecnologías es la misma

INTRODUCCIÓN

Java es un lenguaje de programación desarrollado por Sun Microsystems a principios de 1991. Es un


lenguaje orientado a objetos de propósito general, con el que se van a poder crear tanto programas
asociados a páginas web (Applets) como aplicaciones independientes de estas y para dispositivos móviles.
Todo esto, independiente de la plataforma de computación. Los programas hechos en Java podrán
ejecutarse en cualquier plataforma para la que haya disponible una máquina virtual Java, incluyendo
Windows, Solaris, Macintosh, Linux y muchos otros. En este curso veremos las bases del lenguaje las cuales
servirán para emigrar si así lo desea el participante a otros entornos donde aplicar Java

Programacion Java Página 6 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Módulo 1: Fundamentos y Características del lenguaje Java

Objetivo

Mostrar y enseñar las características principales del lenguaje así como de las partes básicas de las cuales se
compone

Introducción

Java es un lenguaje orientado a objetos, eso implica que su concepción es muy próxima a la forma de pensar
humana. También posee otras características muy importantes:

Es un lenguaje que es compilado, generando archivos de clases compilados, pero estas clases compiladas,
son en realidad interpretadas por la máquina virtual de java. Siendo la máquina virtual de java la que
mantiene el control sobre las clases que se estén ejecutando.

Es un lenguaje multiplataforma: El mismo código java que funciona en un sistema operativo, funcionará en
cualquier otro sistema operativo que tenga instalada la máquina virtual java.

Es un lenguaje seguro: La máquina virtual, al ejecutar el código java, realiza comprobaciones de seguridad,
además el propio lenguaje carece de características inseguras, como por ejemplo los punteros.

Gracias al API de java podemos ampliar el lenguaje para que sea capaz de, por ejemplo, comunicarse con
equipos mediante red, acceder a bases de datos, crear páginas HTML dinámicas, crear aplicaciones visuales
al estilo Windows

Para poder trabajar con java es necesario emplear un software que permita desarrollar en java. Existen
varias alternativas comerciales en el mercado: JBuilder, Visual Age, Visual Café,... y un conjunto de
herramientas shareware, e incluso freeware, que permiten trabajar con java.

Pero todas estas herramientas en realidad se basan en el uso de una herramienta proporcionada por Sun
actualmente absorbido por ORACLE, el creador de java, que es el Java Development Kit (JDK). Nosotros nos
centraremos en el uso de dicha herramienta.

Existen diversas versiones del JDK, siendo posible obtener cualquiera de dichas versiones desde la propia
página de JAVA-ORACLE: [Link]

Programacion Java Página 7 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Java frente a los demás lenguajes


Java es un lenguaje relativamente moderno. Su primer uso en una “tarea seria” de Programación fue la
construcción del navegador HotJava por parte de la empresa Sun en mayo de 1995, y fue a principios de
1996 cuando Sun distribuye la primera versión de Java. Es esta corta edad lo que hace que Java esté más
orientado al mundo web, que no existía cuando, por ejemplo, C fue desarrollado.

También es esto lo que ha hecho que soporte de modo nativo (no mediante el uso de librerías, como C) los
threads, siendo posible aprovechar las ventajas de los sistemas

multiprocesadores.

Las ventajas fundamentales de Java frente a otros lenguajes son el menor periodo de aprendizaje por parte
del programador, llegando a ser un programador productivo en menos tiempo (sencillez) y siendo posible
desarrollar aplicaciones más rápido que en otros lenguajes (sencillez y robustez), lo cual se traduce en el
mundo empresarial en un ahorro de costes.

Sus cualidades de distribuido, seguro e independencia de la plataforma lo hacen ideal para aplicaciones
relacionadas con el mundo web; precisamente a esto es a lo que Java debe su gran difusión y fama. El hecho
de que sea independiente de la máquina y del sistema operativo permite que distintas máquinas con
distintos sistemas operativos se conecten a una misma página web y ejecuten los mismos applets. Además
la seguridad que garantiza Java para los applets impiden que alguien trate de averiguar información sobre
los usuarios que se conectan a la página web o intente dañar sus máquinas.

En cuanto a su capacidad de soporte de threads y su capacidad de sacarle partido a sistemas


multiprocesador lo convierten en un lenguaje más “orientado hacia el futuro “. Estas cualidades podrían dar
pie a que algún día los rendimientos computacionales de Java sean comparables con los de C++ y otros
lenguajes que hoy son computacionalmente más eficientes.

Java 2 Standard Development Kit


En este capítulo haremos un breve repaso del entorno de programación distribuido por ORACLE, jdk.

Dicho entorno de programación es suministrado por ORACLE de forma gratuita, pudiéndose encontrar en la
dirección web: [Link]

Es de consenso que el entorno jdk no es el más adecuado para el desarrollo de aplicaciones Java, debido a
funcionar única y exclusivamente mediante comandos de consola, ya que hoy en día la programación se
suele ayudar de entornos visuales, como JBuilder, JCreator o muchos otros, que facilitan enormemente la
tarea (ver apéndice B). Sin embargo, puede ser un entorno bastante útil para aprender el lenguaje, ya que
aunque los entornos visuales nos hagan mucho trabajo siempre es necesario ir al código para modificarlo y
obtener el comportamiento deseado, lo cual quiere decir que necesitamos dominar el lenguaje y es más fácil
llegar a este dominio escribiendo códigos completos en un entorno “hostil” que no nos ayuda, que
simplemente remodelando códigos ya generados por entornos visuales.

Lenguaje simple

Java posee una curva de aprendizaje muy rápida. Resulta relativamente sencillo escribir Applets interesantes
desde el principio. Todos aquellos familiarizados con C++ encontrarán que Java es más sencillo, ya que se
han eliminado ciertas características, como los punteros. Debido a su semejanza con C y C++, y dado que la
mayoría de la gente los conoce aunque sea de forma elemental, resulta muy fácil aprender Java. Los
programadores experimentados en C++ pueden migrar muy rápidamente a Java y ser productivos en poco
tiempo.

Programacion Java Página 8 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Orientado a objetos

Java fue diseñado como un lenguaje orientado a objetos desde el principio. Los objetos agrupan en
estructuras encapsuladas tanto sus datos como los métodos (o funciones) que manipulan esos datos. La
tendencia del futuro, a la que Java se suma, apunta hacia la programación orientada a objetos,
especialmente en entornos cada vez más complejos y basados en red.

Distribuido

Java proporciona una colección de clases para su uso en aplicaciones de red, que permiten abrir sockets y
establecer y aceptar conexiones con servidores o clientes remotos, facilitando así la creación de aplicaciones
distribuidas.

Interpretado y compilado a la vez

Java es compilado, en la medida en que su código fuente se transforma en una especie de código máquina,
los bytecodes, semejantes a las instrucciones de [Link] otra parte, es interpretado, ya que los
bytecodes se pueden ejecutar directamente sobre cualquier máquina a la cual se hayan portado el
intérprete y el sistema de ejecución en tiempo real (run-time).

Robusto

Java fue diseñado para crear software altamente fiable. Para ello proporciona numerosas comprobaciones
en compilación y en tiempo de ejecución. Sus características de memoria liberan a los programadores de
una familia entera de errores (la aritmética de punteros), ya que se ha prescindido por completo los
punteros, y la recolección de basura elimina la necesidad de liberación explícita de memoria.

Seguro

Dada la naturaleza distribuida de Java, donde las applets se bajan desde cualquier punto de la Red, la
seguridad se impuso como una necesidad de vital importancia. A nadie le gustaría ejecutar en su
computadora programas con acceso total a su sistema, procedentes de fuentes desconocidas. Así que se
implementaron barreras de seguridad en el lenguaje y en el sistema de ejecución en tiempo real.

Mecanismos de seguridad
Java fue diseñado para ofrecer las siguientes medidas de seguridad básicas:

 Uso de un lenguaje de programación seguro. El lenguaje de programación Java está diseñado para
ser seguro, como hemos comentado en el apartado anterior.

 Integración de un sistema de control de permisos para los programas. Java define un mecanismo
(denominado mecanismo del cajón de arena) que permite controlar que se le permite hacer a un
programa y controlar como accede a los recursos.(GESTOR DE RECURSOS)

 Encriptación y uso de certificados. Se definen mecanismos para que los programadores puedan
firmar el código, de manera que los usuarios puedan verificar quien es el propietario del código y
que este no ha sido modificado después de ser firmado.

La seguridad se basa en tres componentes fundamentales del entorno de ejecución:

Programacion Java Página 9 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

1. El cargador de clases (Class Loader), que determina como y cuando pueden cargar código los
programas y garantiza que los componentes del sistema no han sido remplazados.

2. El verificador de archivos de clases (Class file verifier), que garantiza que el código tiene el formato
correcto, que el bytecode no viola las restricciones de seguridad de tipos de la JVM, que las pilas
internas no puedan desbordarse ni por arriba ni por abajo y que las instrucciones en bytecode
tengan parámetros de tipos correctos.

3. El gestor de seguridad (Security Manager), que controla el acceso a los recursos en tiempo de
ejecución. Los recursos sobre los que tiene control son múltiples: E/S de red y ficheros, creación de
cargadores de clases, manipulación de hilos de ejecución, ejecución de programas externos (del
SO), detener la JVM, cargar código nativo en la máquina virtual, realizar determinadas operaciones
en el entorno de ventanas o cargar ciertos tipos de clases.

Indiferente a la arquitectura
Java está diseñado para soportar aplicaciones que serán ejecutadas en los más variados entornos de red,
desde Unix a Windows Nt, pasando por Mac y estaciones de trabajo, sobre arquitecturas distintas y con
sistemas operativos diversos. Para acomodar requisitos de ejecución tan variopintos, el compilador de Java
genera bytecodes: un formato intermedio indiferente a la arquitectura diseñada para transportar el código
eficientemente a múltiples plataformas hardware y software. El resto de problemas los soluciona el
intérprete de Java.

Portable

La indiferencia a la arquitectura representa sólo una parte de su portabilidad. Además, Java especifica los
tamaños de sus tipos de datos básicos y el comportamiento de sus operadores aritméticos, de manera que
los programas son iguales en todas las plataformas. Estas dos últimas características se conocen como la
Máquina Virtual Java (JVM).

Multihebra

Hoy en día ya se ven como terriblemente limitadas las aplicaciones que sólo pueden ejecutar una acción a la
vez. Java soporta sincronización de múltiples hilos de ejecución (multithreading) a nivel de lenguaje,
especialmente útiles en la creación de aplicaciones de red distribuidas. Así, mientras un hilo se encarga de la
comunicación, otro puede interactuar con el usuario mientras otro presenta una animación en pantalla y
otro realiza cálculos.

Dinámico

El lenguaje Java y su sistema de ejecución en tiempo real son dinámicos en la fase de enlazado. Las clases
sólo se enlazan a medida que son necesitadas. Se pueden enlazar nuevos módulos de código bajo demanda,
procedente de fuentes muy variadas, incluso desde la Red.

Aplicaciones

Las aplicaciones Java están típicamente compiladas en un bytecode, aunque la compilación en código
máquina nativo también es posible. En el tiempo de ejecución, el bytecode es normalmente interpretado o
compilado a código nativo para la ejecución, aunque la ejecución directa por hardware del bytecode por un
procesador Java también es posible.

La implementación original y de referencia del compilador, la máquina virtual y las bibliotecas de clases de
Java fueron desarrolladas por Sun Microsystems en 1995. Desde entonces, Sun ha controlado las
especificaciones, el desarrollo y evolución del lenguaje a través del Java Community Process, si bien otros

Programacion Java Página 10 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

han desarrollado también implementaciones alternativas de estas tecnologías de Sun, algunas incluso bajo
licencias de software libre. Actualmente Sun pertenece a ORACLE.

Tipos de Datos, Identificadores e Instrucciones


Variables

Las variables son localidades de memoria en las que pueden almacenarse datos. Cada una tiene un nombre,
un tipo y valor. Java tiene tres tipos de variables: de instancia, de clase y locales.

 Variables de instancia.

Se utilizan para definir los atributos de un objeto.

 Variables de clase.

Son similares a las variables de instancia, con la excepción de que sus valores son los mismos para
todas las instancias de la clase.

 Variable locales.

Se declaran y se utilizan dentro de las definiciones de los métodos.

* A diferencia de otros lenguajes, Java no tiene variables globales, es decir , variables que son vistas en
cualquier parte del programa.

Java es un lenguaje "fuertemente tipeado o tipificado" por lo que es necesario especificar el tipo de dato
para cada una de las variables que se vayan a utilizar en un programa. El nombre de la variable debe de ser
un identificador válido, y se usa para referirse a los datos que contiene una variable.

El tipo de una variable determina los valores que puede almacenar y las operaciones que se pueden hacer
sobre ella. Para dar a una variable un tipo y un nombre, se escribe una declaración de una variable, que
tiene la siguiente forma:

TipoDato nombreVariable;

String nombre; // variable de tipo String

int edad; // variable de tipo int

Punto p; // variable del tipo Punto

Se pueden escribir varios nombres de variables del mismo tipo en una sola línea,

int x, y, z;

String nombre, apellido;

También se puede asignar un valor inicial a las variables al momento de crearlas,

String nombre, apellido="MiApellido";

int edad = 24;

Tipos de Datos

Programacion Java Página 11 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Las variables en Java pueden ser uno de los siguientes tipos:

 Tipo primitivo.

Una variable de tipo primitivo contiene un solo valor del tamaño y formato apropiado de su tipo: un
número, un carácter, o un valor booleano.

La tabla siguiente lista los tipos de datos primitivos soportados por Java.

Tipo Descripción Tamaño/Formato

Números enteros

byte Entero byte 8-bit 2's

short Entero corto 16-bit 2's

int Entero 32-bit 2's

long Entero largo 64-bit 2's

Números reales

float Punto flotante 32-bit IEEE 754

double Punto flotante de doble presición 64-bit IEEE 754

Otros tipos

char Un solo carácter 16-bit caracteres Unicode

boolean Un valor booleano true o false

En Java, cualquier numérico con punto flotante automáticamente se considera double. Para que sea
considerado float se agrega una letra "f" o "F" al final del valor.

double d = 10.50;
float f = 10.50F;

 Referencia.

Los arreglos, las clases y las interfaces son del tipo referencia. El valor de una variable del tipo referencia es
una dirección de un conjunto de valores representados por una variable.

Las referencias en Java no son como en C++, éstas son identificadores de instancias de alguna clase en
particular.

Ej.

Programacion Java Página 12 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

String cad; //referencia a un objeto de la clase String

Punto p; //referencia a un objeto de la clase Punto

int[] var_arreglo; //referencia a un arreglo de enteros

Identificadores
Un identificador es una secuencia de caracteres comenzando por una letra y conteniendo letras y números.
Los identificadores no se limitan a los caracteres ASCII, si el editor de texto lo soporta, se pueden escribir
identificadores utilizando caracteres Unicode.

Las letras Java incluyen los caracteres ASCII A-Z y a-z. Los digitos Java incluyen los digitos ASCII 0-9. Para
propósitos de construir identificadores, los caracteres ASCII $ y _ son también considerados letras Java. No
hay un límite en lo concerniente al número de caracteres que pueden tener los identificadores.

Estos son algunos ejemplos de identificadores válidos:

_varx $var1 MAX_NUM var2

Palabras clave
La siguiente tabla muestra las palabras claves de Java, éstas son reservadas y no pueden ser utilizadas como
identificadores.

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

* Son palabras claves de Java que no son usadas actualmente.

** Palabra clave agregada en Java 2

true, false, and null no son palabras claves pero son palabras reservadas, así que tampoco pueden ser
utilizadas como identificadores.

Programacion Java Página 13 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Expresiones y Operadores

 Expresión

Una expresión es una combinación de variables, operadores y llamadas de métodos construida de acuerdo a
la sintaxis del lenguaje que devuelve un valor.

El tipo de dato del valor regresado por una expresión depende de los elementos usados en la expresión.

 Operadores

Los operadores son símbolos especiales que por lo común se utilizan en expresiones.

La tabla siguiente muestra los distintos tipos de operadores que utiliza Java.

Operador Significado Ejemplo

Operadores aritméticos

+ Suma a+b

- Resta a-b

* Multiplicación a*b

/ División a/b

% Módulo a%b

Operadores de asignación

= Asignación a=b

+= Suma y asignación a += b (a=a + b)

-= Resta y asignación a -= b (a=a - b)

*= Multiplicación y asignación a *= b (a=a * b)

/= División y asignación a / b (a=a / b)

%= Módulo y asignación a % b (a=a % b)

Operadores relacionales

== Igualdad a == b

!= Distinto a != b

Programacion Java Página 14 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

< Menor que a<b

> Mayor que a>b

<= Menor o igual que a <= b

>= Mayor o igual que a >= b

Operadores especiales

++ Incremento a++ (postincremento)


++a (preincremento)

-- Decremento a-- (postdecremento)


--a (predecremento)

(tipo)expr Cast a = (int) b

+ Concatenación de cadenas a = "cad1" + "cad2"

. Acceso a variables y métodos a = obj.var1

() Agrupación de expresiones a = (a + b) * c

La tabla siguiente muestra la precedencia asignada a los operadores, éstos son listados en orden de
precedencia.

Los operadores en la misma fila tienen igual precedencia

Operador Notas

. [] () Los corchetes se utilizan para los arreglos

++ -- ! ~ ! es el NOT lógico y ~ es el complemento de bits

new (tipo)expr new se utiliza para crear instancias de clases

* / % Multiplicativos

+- Aditivos

<< >> >>> Corrimiento de bits

< > <= >= Relacionales

== != Igualdad

& AND (entre bits)

^ OR exclusivo (entre bits)

Programacion Java Página 15 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

| OR inclusivo (entre bits)

&& AND lógico

|| OR lógico

?: Condicional

= += -= *= /= %= &= ^= |= <<= >>= >>>= Asignación

Todos los operadores binarios que tienen la misma prioridad (excepto los operadores de asignación) son
evaluados de izquierda a derecha.

Los operadores de asignación son evaluados de derecha a izquierda.

Programacion Java Página 16 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Módulo 2. Estructuras de Flujo y Control de Datos

Objetivo

Mostrar los diferentes mecanismos de flujos de control y bucles que el lenguaje Java le da Soporte y como
utilizarlos

Introducción

El control del flujo es la manera que tiene un lenguaje de programación de provocar que el flujo de la
ejecución avance y se ramifique en función de los cambios de estado de los datos. Java, en este aspecto, no
utiliza los principios de diseño orientado a objetos, sino que las sentencias de control del flujo del programa
se han tomado del C/C++. A continuación se tratan todos los mecanismos que proporciona Java para
conseguir este control y decidir qué partes del código ejecutar.

Sentencia

Una instrucción o sentencia representa la tarea más sencilla que se puede realizar en un programa.

Sentencias de expresión

Los siguientes tipos de expresiones pueden ser hechas dentro de una sentencia terminando la expresión con
punto y coma (;):

 Expresiones de asignación
 Cualquier uso de los operadores ++ y –
 Llamada de métodos
 Expresiones de creación de objetos

Esta clase de sentencias son llamadas sentencias de expresión.

Ej.

valorA = 8933.234; // asignación


valorA++; // incremento
[Link](valorA); // llamada a un método
Integer objInt = new Integer(4); // creación de objetos

Sentencias de declaración de variables

Las sentencias de declaración de variables se utilizan para declarar variables.

int bValue;
double aValue = 8933.234;
String varCad;

Programacion Java Página 17 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Sentencias de control de flujo

Las sentencias de control de flujo determinan el orden en el cual serán ejecutadas otro grupo de sentencias.
Las sentencias if y for son ejemplos de sentencias de control de flujo.

Bloque de sentencias

Un bloque es un grupo de cero o más sentencias encerradas entre llaves ( { y } ). Se puede poner un bloque
de sentencias en cualquier lugar en donde se pueda poner una sentencia individual.

Estructuras de Control de Flujo


Las sentencias de control de flujo se pueden utilizar para ejecutar sentencias condicionalmente, para
ejecutar de manera repetida un bloque de sentencias y en general para cambiar la secuencia normal de un
programa.

La sentencia if

La sentencia if permite llevar a cabo la ejecución condicional de sentencias.

if ( Expresion ){
sentencias;
}

Se ejecutan las sentencias si al evaluar la expresión se obtiene un valor booleano true.

if ( Expresion ){
sentenciasA;
}
else{
sentenciasB;
}

Si al evaluar la expresión se obtiene un valor booleano true se ejecutarán las sentenciasA, en caso contrario
se ejecutarán las sentenciasB.

La sentencia switch

Cuando se requiere comparar una variable con una serie de valores diferentes, puede utilizarse la sentencia
switch, en la que se indican los posibles valores que puede tomar la variable y las sentencias que se tienen
que ejecutar sí es que la variable coincide con alguno de dichos valores.

switch( variable ){
case valor1:
sentencias;
break;
case valor2:
sentencias;
break;

...

case valorN:

Programacion Java Página 18 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

sentencias;
break;
default:
sentencias;
}

Cada case ejecutará las sentencias correspondientes, con base en el valor de la variable, que deberá de
evaluarse con valores de tipo byte, char, short o int.

Si el valor de la variable no coincide con ningún valor, entonces se ejecutan las sentencias por default, sí es
que las hay.

La sentencia break al final de cada case transfiere el control al final de la sentencia switch; de esta manera,
cada vez que se ejecuta un case todos los enunciados case restantes son ignorados y termina la operación
del switch.

Instrucciones de Estructura de Datos y Bucles

El ciclo for

El ciclo for repite una sentencia, o un bloque de sentencias, mientras una condición se cumpla. Se utiliza la
mayoría de las veces cuando se desea repetir una sentencia un determinado número de veces.

La forma general de la sentencia for es la siguiente;

for(inicialización;condición;incremento){
sentencias;
}
 En su forma más simple, la inicialización es una sentencia de asignación que se utiliza para
establecer una variable que controle el ciclo.

 La condición es una expresión que comprueba la variable que controla el ciclo y determinar cuando
salir del ciclo.

 El incremento define la manera en como cambia la variable que controla el ciclo.

Ciclos While y Do … While

Los ciclos while y do-while, al igual que los ciclos for repiten la ejecución de un bloque de sentencias
mientras se cumpla una condición específica.

La sentencia while

El formato de la sentencia while es la siguiente:


while (condición){
sentencias;
}

Programacion Java Página 19 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

La condición es una condición booleana, que mientras tenga el valor true permite que se ejecuten las
sentencias correspondientes.

La sentencia do-while

Al contrario de los ciclos for y while que comprueban una condición en lo alto del ciclo, el ciclo do-while la
examina en la parte más baja del mismo. Esta característica provoca que un ciclo do-while siempre se
ejecute por lo menos una vez.

El formato de la sentencia do-while es el siguiente:

do{

sentencias;

}while (condición);

break

La sentencia break tiene dos usos. El primer uso es terminar un case en la sentencia switch. El segundo es
forzar la terminación inmediata de un ciclo, saltando la prueba condicional normal del ciclo.

continue

La sentencia continue es similar a la sentencia break. Sin embargo, en vez de forzar la terminación del ciclo,
continue forza la siguiente iteración y salta cualquier código entre medias.

return

Se utiliza la sentencia return para provocar la salida del método actual; es decir, return provocará que el
programa vuelva al código que llamó al método.

La sentencia return puede regresar o no un valor. Para devolver un valor, se pone el valor después de la
palabra clave return.

return valor;

El tipo de dato del valor regresado debe ser el mismo que el que se especifica en la declaración del método.

Cuando un método es declarado void, el método no regresa ningún valor.

return;

Programacion Java Página 20 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Laboratorio Modulo 2. Estructuras de Control y Flujo de Datos

Objetivo. Utilizar las instrucciones de control de Java para generar los programas solicitados

1. Escribir un programa que solicite ingresar 10 notas de alumnos y nos informe cuántos tienen notas
mayores o iguales a 7 y cuántos menores.

2. Realizar un programa que permita cargar dos listas de 15 valores cada una. Informar con un mensaje cual
de las dos listas tiene un valor acumulado mayor (mensajes "Lista 1 mayor", "Lista 2 mayor", "Listas iguales")
Tener en cuenta que puede haber dos o más estructuras repetitivas en un algoritmo.

Programacion Java Página 21 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Módulo 3. Programación Orientada a Objetos

Objetivos

Explicar y mostrar los conceptos básicos de la programación orientada a objetos (POO)

Introducción
El elemento básico de la programación orientada a objetos en Java es una clase. Una clase define la forma y
comportamiento de un objeto. Todo en Java gira alrededor de estos conceptos, por ello, una vez que se han
repasado los mecanismos básicos del lenguaje en cuestiones ya conocidas; esta sección se adentra en la
ampliación de los conceptos teóricos enfocados hacia el estilo de programación orientada a objetos de Java.

Clases y objetos

Objeto

Un objeto es una encapsulación genérica de datos y de los procedimientos para manipularlos.

Al igual que los objetos del mundo real, los objetos de software tienen un estado y un comportamiento. El
estado de los objetos se determina a partir de una o más variables y el comportamiento con la
implementación de métodos.

La siguiente figura muestra la representación cómun de los objetos de software

Como se observa en la figura, todos los objetos tienen una parte pública (su comportamiento) y una parte
privada (su estado). En este caso, hicimos una vista transversal pero desde el mundo exterior, el objeto se
observará como una esfera.

Clase

Una clase está formada por los métodos y las variables que definen las características cómunes a todos los
objetos de esa clase. Precisamente la clave de la OOP está en abstraer los métodos y los datos comunes a un
conjunto de objetos y almacenarlos en una clase.

Una clase equivale a la generalización de un tipo específico de objetos. Una instancia es la concreción de
una clase.

Programacion Java Página 22 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Clase X

En la figura anterior, el objeto A y el objeto B son instancias de la clase X.

Cada uno de los objetos tiene su propia copia de las variables definidas en la clase de la cual son
instanciados y comparten la misma implementación de los métodos.

Mensajes y métodos

El modelado de objetos no sólo tiene en consideración los objetos de un sistema, sino también sus
interrelaciones.

Mensaje

Los objetos interactúan enviándose mensajes unos a otros. Tras la recepción de un mensaje el objeto
actuará. La acción puede ser el envío de otros mensajes, el cambio de su estado, o la ejecución de cualquier
otra tarea que se requiera que haga el objeto.

Método

Un método se implementa en una clase, y determina cómo tiene que actuar el objeto cuando recibe un
mensaje.

Cuando un objeto A necesita que el objeto B ejecute alguno de sus métodos, el objeto A le manda un
mensaje al objeto B.

Al recibir el mensaje del objeto A, el objeto B ejecutará el método adecuado para el mensaje recibido.

Encapsulamiento

Programacion Java Página 23 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Como se puede observar de los diagramas, las variables del objeto se localizan en el centro o núcleo del
objeto. Los métodos rodean y esconden el núcleo del objeto de otros objetos en el programa. Al
empaquetamiento de las variables de un objeto con la protección de sus métodos se le llama
encapsulamiento. Típicamente, el encapsulamiento es utilizado para esconder detalles de la puesta en
práctica no importantes de otros objetos. Entonces, los detalles de la puesta en práctica pueden cambiar en
cualquier tiempo sin afectar otras partes del programa.

El encapsulamiento de variables y métodos en un componente de software ordenado es, todavía, una


simple idea poderosa que provee dos principales beneficios a los desarrolladores de software:

 Modularidad, esto es, el código fuente de un objeto puede ser escrito, así como darle
mantenimiento, independientemente del código fuente de otros objetos. Así mismo, un objeto
puede ser transferido alrededor del sistema sin alterar su estado y conducta.

 Ocultamiento de la información, es decir, un objeto tiene una "interfaz publica" que otros objetos
pueden utilizar para comunicarse con él. Pero el objeto puede mantener información y métodos
privados que pueden ser cambiados en cualquier tiempo sin afectar a los otros objetos que
dependan de ello.

Los objetos proveen el beneficio de la modularidad y el ocultamiento de la información. Las clases proveen
el beneficio de la reutilización. Los programadores de software utilizan la misma clase, y por lo tanto el
mismo código, una y otra vez para crear muchos objetos.

En las implantaciones orientadas a objetos se percibe un objeto como un paquete de datos y


procedimientos que se pueden llevar a cabo con estos datos. Esto encapsula los datos y los procedimientos.
La realidad es diferente: los atributos se relacionan al objeto o instancia y los métodos a la clase. ¿Por qué se
hace así? Los atributos son variables comunes en cada objeto de una clase y cada uno de ellos puede tener
un valor asociado, para cada variable, diferente al que tienen para esa misma variable los demás objetos.
Los métodos, por su parte, pertenecen a la clase y no se almacenan en cada objeto, puesto que sería un
desperdicio almacenar el mismo procedimiento varias veces y ello va contra el principio de reutilización de
código.

Herencia

La herencia es un mecanismo que permite la definición de una clase a partir de la definición de otra ya
existente. La herencia permite compartir automáticamente métodos y datos entre clases, subclases y
objetos.

La herencia está fuertemente ligada a la reutilización del código en la OOP. Esto es, el código de cualquiera
de las clases puede ser utilizado sin más que crear una clase derivada de ella, o bien una subclase.

Hay dos tipos de herencia: Herencia Simple y Herencia Múltiple. La primera indica que se pueden definir
nuevas clases solamente a partir de una clase inicial mientras que la segunda indica que se pueden definir
nuevas clases a partir de dos o más clases iniciales. Java sólo permite herencia simple.

Superclase y Subclases
El concepto de herencia conduce a una estructura jerárquica de clases o estructura de árbol, lo cual significa
que en la OOP todas las relaciones entre clases deben ajustarse a dicha estructura.

En esta estructura jerárquica, cada clase tiene sólo una clase padre. La clase padre de cualquier clase es
conocida como su superclase. La clase hija de una superclase es llamada una subclase.

Programacion Java Página 24 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

 Una superclase puede tener cualquier número de subclases.


 Una subclase puede tener sólo una superclase.

o A es la superclase de B, C y D.

o D es la superclase de E.

o B, C y D son subclases de A.

o E es una subclase de D.

Polimorfismo
Otro concepto de la OOP es el polimorfismo. Un objeto solamente tiene una forma (la que se le asigna
cuando se construye ese objeto) pero la referencia a objeto es polimórfica porque puede referirse a objetos
de diferentes clases (es decir, la referencia toma múltiples formas). Para que esto sea posible debe haber
una relación de herencia entre esas clases. Por ejemplo, considerando la figura anterior de herencia se
tiene que:

 Una referencia a un objeto de la clase B también puede ser una referencia a un objeto de la clase A.

 Una referencia a un objeto de la clase C también puede ser una referencia a un objeto de la clase A.

 Una referencia a un objeto de la clase D también puede ser una referencia a un objeto de la clase A.

 Una referencia a un objeto de la clase E también puede ser una referencia a un objeto de la clase D.

 Una referencia a un objeto de la clase E también puede ser una referencia a un objeto de la clase A.

Abstracción

Volviendo a la figura anterior de la relación de herencia entre clases, se puede pensar en una jerarquía de
clase como la definición de conceptos demasiado abstractos en lo alto de la jerarquía y esas ideas se
convierten en algo más concreto conforme se desciende por la cadena de la superclase.

Sin embargo, las clases hijas no están limitadas al estado y conducta provistos por sus superclases; pueden
agregar variables y métodos además de los que ya heredan de sus clases padres. Las clases hijas pueden,
también, sobreescribir los métodos que heredan por implementaciones especializadas para esos métodos.
De igual manera, no hay limitación a un sólo nivel de herencia por lo que se tiene un árbol de herencia en el

Programacion Java Página 25 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

que se puede heredar varios niveles hacia abajo y mientras más niveles descienda una clase, más
especializada será su conducta.

La herencia presenta los siguientes beneficios:

o Las subclases proveen conductas especializadas sobre la base de elementos comunes


provistos por la superclase. A través del uso de herencia, los programadores pueden
reutilizar el código de la superclase muchas veces.

o Los programadores pueden implementar superclases llamadas clases abstractas que


definen conductas "genéricas". Las superclases abstractas definen, y pueden implementar
parcialmente, la conducta pero gran parte de la clase no está definida ni implementada.
Otros programadores concluirán esos detalles con subclases especializadas.

Programacion Java Página 26 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Módulo 4. Trabajando con Clases y Objetos en Java

Objetivo
Codificar en lenguaje Java los conceptos de Programación Orientada a Objetos

Introducción
Una vez que hemos entendido la parte teórica de la programación orientada a objetos , es fundamental
poder aterrizarla en código, ya que de lo contrario no nos serviría de nada. Dicha aplicación de la teoría en
código es realmente sencilla y como vera a continuación el participante

Definición de clases
La definición de una clase especifica cómo serán los objetos de dicha clase, esto es, de que variables y de
que métodos constarán.

La siguiente es la definición más simple de una clase:

class nombreClase /* Declaración de la clase */


{

/* Aquí va la definición de variables y métodos */

}
Como se puede observar, la definición de una clase consta de dos partes fundamentales:

La declaración de la clase

Indica el nombre de la clase precedido por la palabra clave class.

El cuerpo de la clase

El cuerpo de la clase sigue a la declaración de la clase y está contenido entre la pareja de llaves ({ y }). El
cuerpo de la clase contiene las declaraciones de las variables de la clase, y también la declaración y la
implementación de los métodos que operan sobre dichas variables.

Declaración de variables de instancia

El estado de un objeto está representado por sus variables (variables de instancia). Las variables de instancia
se declaran dentro del cuerpo de la clase. Típicamente, las variables de instancia se declaran antes de la
declaración de los métodos, pero esto no es necesariamente requerido.

 Implementación de métodos

Los métodos de una clase determinan los mensajes que un objeto puede recibir.

Las partes fundamentales de un método son el valor de retorno, el nombre, los argumentos (opcionales) y

Programacion Java Página 27 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

su cuerpo. Además, un método puede llevar otros modificadores opcionales que van al inicio de la
declaración del método y que se analizarán más adelante. La sintaxis de un método es la siguiente:

<otrosModificadores> valorRetorno nombreMetodo( <lista de argumentos> )

/* Cuerpo del método */

sentencias;

Los signos <> indican que no son obligatorios.

Los métodos en Java pueden ser creados únicamente como parte de una clase. Cuando se llama a un
método de un objeto se dice comúnmente que se envia un mensaje al objeto.

/* [Link] */

class Usuario
{
String nombre;
int edad;
String direccion;

void setNombre(String n)
{
nombre = n;
}

String getNombre()
{
return nombre;
}

void setEdad(int e)
{
edad = e;
}

int getEdad()
{
return edad;
}

void setDireccion(String d)
{
direccion = d;
}

Programacion Java Página 28 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

String getDireccion()
{
return direccion;
}
}

Constructores y creación de objetos

Una vez que se tiene definida la clase a partir de la cual se crearán los objetos se está en la posibilidad de
instanciar los objetos requeridos.

Para la clase Usuario del ejemplo anterior podemos crear un objeto de la siguiente manera:

Usuario usr1; //usr1 es una variable del tipo Usuario

usr1 = new Usuario();

La primera línea corresponde a la declaración del objeto, es decir, se declara una variable del tipo de objeto
deseado.

La segunda línea corresponde a la iniciación del objeto.

El operador new

El operador new crea una instancia de una clase asignando la cantidad de memoria necesaria de acuerdo al
tipo de objeto. El operador new se utiliza en conjunto con un constructor. El operador new regresa una
referencia a un nuevo objeto.

Constructores

Un constructor es un tipo específico de método que siempre tiene el mismo nombre que la clase, y que se
utiliza cuando se desean crear objetos de dicha clase, es decir, se utiliza al crear e iniciar un objeto de una
clase.

Constructores múltiples

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

Para la clase Usuario del ejemplo anterior no se especificó ningún constructor, sin embargo, Java
proporciona un constructor por omisión que inicia las variables del objeto a sus valores predeterminados.

Ej.

/* [Link] */

class ProgUsuario
{
public static void main(String args[])
{
Usuario usr1, usr2; /* Se declaran dos objetos de la clase Usuario */
boolean si_no;

Programacion Java Página 29 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

usr1 = new Usuario(); /* Se utiliza el constructor por omisión */


si_no = usr1 instanceof Usuario;

if(si_no == true)
[Link]("\nEl objeto usr1 SI es instancia de Usuario.");
else
[Link]("\nEl objeto usr1 NO es instancia de Usuario.");

usr2 = usr1; /* usr1 y usr2 son el mismo objeto */


si_no = usr2 instanceof Usuario;

if(si_no == true)
[Link]("\nEl objeto usr2 SI es instancia de Usuario.");
else
[Link]("\nEl objeto usr2 NO es instancia de Usuario.");
}
}

Acceso a variables y métodos

Una vez que se ha creado un objeto, seguramente se querrá hacer algo con él. Tal vez se requiera obtener
información de éste, se quiera cambiar su estado, o se necesite que realice alguna tarea.

Los objetos tienen dos formas de hacer esto:

 Manipular sus variables directamente.

Para accesar a las variables de un objeto se utiliza el operador punto ( . ). La sintaxis es la siguiente:

[Link];

 Llamar a sus métodos.

Para llamar a los métodos de un objeto, se utiliza también el operador punto ( . ). La sintaxis es la siguiente:

[Link]( <lista de argumentos opcionales> );

Ejemplo

/* [Link] */

class Usuario2
{
String nombre;
int edad;
String direccion;

Usuario2( ) /* Equivale al contructor por omisión */


{
nombre = null;
edad = 0;

Programacion Java Página 30 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

direccion = null;
}

Usuario2(String nombre, int edad, String direccion)


{
[Link] = nombre;
[Link] = edad;
[Link] = direccion;
}

Usuario2(Usuario2 usr)
{
nombre = [Link]();
edad = [Link]();
direccion = [Link]();
}

void setNombre(String n)
{
nombre = n;
}

String getNombre()
{
return nombre;
}

void setEdad(int e)
{
edad = e;
}

int getEdad()
{
return edad;
}

void setDireccion(String d)
{
direccion = d;
}

String getDireccion()
{
return direccion;
}
}

Ejemplo
/* [Link] */
class ProgUsuario2
{

Programacion Java Página 31 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

void imprimeUsuario(Usuario2 usr)


{
// [Link] equivale en este caso a [Link]()
[Link]("\nNombre: " + [Link] );
[Link]("Edad: " + [Link]() );
[Link]("Direccion: " + [Link]() +"\n");
}

public static void main(String args[])


{
ProgUsuario2 prog = new ProgUsuario2( );
Usuario2 usr1,usr2; /* Se declaran dos objetos de la clase Usuario2 */

/* Se utiliza el constructor por omisión */


usr1 = new Usuario2( );
[Link](usr1);

/* Se utiliza el segundo constructor de Usuario2 */


usr2 = new Usuario2("Eduardo",24,"Mi direccion");
[Link](usr2);

/* Se utiliza el tercer constructor de Usuario2 */


usr1 = new Usuario2(usr2);

/* En este caso [Link]("nuevoValor"); equivale


a [Link] = "nuevoValor"; */
[Link]("Otra direccion");

[Link](usr1);
[Link](usr2);
}
}

Variables y métodos de clase

Variables de clase

Las variables de clase son variables cuyos valores son los mismos para la clase y para todas sus instancias.

Para indicar que una variable es una variable de clase se utiliza la palabra clave static en la declaración de la
variables:
static tipoVariable nombreVariable;

Métodos de clase
Los métodos de clase al igual que las variables de clase, se aplican a la clase como un todo y no a sus
instancias.

Se utiliza de igual manera la palabra clave static para indicar que un método es un método de clase:

static valorRetorno nombreMetodo( <lista argumentos opcionales> )

Programacion Java Página 32 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

{
/* cuerpo del método */
}

Para acceder a las variables o métodos de clase se utiliza el mismo operador punto ( . ).

Aunque se puede acceder a las variables y métodos de clase a través de un objeto, está permitido y se
recomienda utilizar mejor el nombre de la clase,

/* Utilizar esto */
[Link];
[Link]();

/* en lugar de esto */
[Link];
[Link]();

Ejemplo

/* [Link] */

class Usuario3
{
static char MAS = 'm';
static char FEM = 'f';

String nombre;
int edad;
String direccion;
char sexo;

Usuario3( )
{
nombre = null;
edad = 0;
direccion = null;
sexo = '\0';
}

Usuario3(String nombre, int edad, String direccion,char sexo)


{
[Link] = nombre;
[Link] = edad;
[Link] = direccion;
[Link] = sexo;
}

Usuario3(Usuario3 usr)
{
nombre = [Link]();
edad = [Link]();
direccion = [Link]();

Programacion Java Página 33 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

sexo = [Link]();
}

void setNombre(String n)
{
nombre = n;
}

String getNombre( )
{
return nombre;
}

void setEdad(int e)
{
edad = e;
}

int getEdad()
{
return edad;
}

void setDireccion(String d)
{
direccion = d;
}

String getDireccion( )
{
return direccion;
}

void setSexo(char s)
{
sexo = s;
}

char getSexo( )
{
return sexo;
}

public String toString()


{
return nombre;
}
}

/* [Link] */

class ProgUsuario3
{

Programacion Java Página 34 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

static int NUM_USUARIOS = 0;


static [Link] usuarios = new [Link]();

String nombreObj = null;

ProgUsuario3(String nombre)
{
[Link] = nombre;
}

static int getNumUsuarios()


{
return NUM_USUARIOS;
}

static void imprimeUsuario(Usuario3 usr)


{
[Link]("\nNombre: " + [Link] );
[Link]("Edad: " + [Link]() );
[Link]("Sexo: " + [Link]() );
[Link]("Direccion: " + [Link]() );
}

void addUsuario(Usuario3 usr)


{
[Link](usr);
[Link]([Link]( )+ " agregado por el "+ [Link]() +",");
NUM_USUARIOS ++;
}

void delUsuario(Usuario3 usr)


{
boolean b = [Link](usr);
if( b == true )
{
NUM_USUARIOS--;
[Link]([Link]( )+ " eliminado por el "+ [Link]() +",");
}
else [Link]("No se pudo eliminar al usuario.");
}

public String toString()


{
return nombreObj;
}

public static void main(String args[])


{
ProgUsuario3 obj1 = new ProgUsuario3("objeto1");
ProgUsuario3 obj2 = new ProgUsuario3("objeto2");

Usuario3 usr1,usr2,usr3,usr4;

Programacion Java Página 35 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

usr1 = new Usuario3( );


usr2 = new Usuario3("Usuario B",24,"La direccion A",[Link]);
usr1 = new Usuario3(usr2);
[Link]("Usuario A");
usr3 = new Usuario3("Usuario C",35,"La direccion C",[Link]);
usr4 = new Usuario3("Usuario D",15,"La direccion D",[Link]);

[Link](usr1);
[Link]( "\t Total: " +[Link]() );
[Link](usr2);
[Link]( "\t Total: " +[Link]() );
[Link](usr3);
[Link]( "\t Total: " +ProgUsuario3.NUM_USUARIOS );
[Link](usr4);
[Link]( "\t Total: " +getNumUsuarios() +"\n");

[Link](usr4);
[Link]( "\t Total: " +[Link]() );
[Link](usr3);
[Link]( "\t Total: " +[Link]() );
[Link](usr2);
[Link]( "\t Total: " +ProgUsuario3.NUM_USUARIOS );
[Link](usr1);
[Link]( "\t Total: " +getNumUsuarios() +"\n");
}
}

Heredando clases en Java

El concepto de herencia conduce a una estructura jerárquica de clases o estructura de árbol, lo cual significa
que en la OOP todas las relaciones entre clases deben ajustarse a dicha estructura.

En esta estructura jerárquica, cada clase tiene sólo una clase padre. La clase padre de cualquier clase es
conocida como su superclase. La clase hija de una superclase es llamada una subclase.

De manera automática, una subclase hereda las variables y métodos de su superclase (más adelante se
explica que pueden existir variables y métodos de la superclase que la subclase no puede heredar. Véase
Modificadores de Acceso). Además, una subclase puede agregar nueva funcionalidad (variables y métodos)
que la superclase no tenía.

 Los constructores no son heredados por las subclases.

Para crear una subclase, se incluye la palabra clave extends en la declaración de la clase.

class nombreSubclase extends nombreSuperclase{

En Java, la clase padre de todas las clases es la clase Object y cuando una clase no tiene una superclase
explícita, su superclase es Object.

Programacion Java Página 36 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Sobrecarga de métodos y de constructores


La firma de un método es la combinación del tipo de dato que regresa, su nombre y su lista de argumentos.

La sobrecarga de métodos es la creación de varios métodos con el mismo nombre pero con diferentes
firmas y definiciones. Java utiliza el número y tipo de argumentos para seleccionar cuál definición de método
ejecutar.

Java diferencia los métodos sobrecargados con base en el número y tipo de argumentos que tiene el
método y no por el tipo que devuelve.

Tambien existe la sobrecarga de constructores: Cuando en una clase existen constructores múltiples, se dice
que hay sobrecarga de constructores.

Ejemplo

/* Métodos sobrecargados */
int calculaSuma(int x, int y, int z){
...
}
int calculaSuma(double x, double y, double z){
...
}

/* Error: estos métodos no están sobrecargados */


int calculaSuma(int x, int y, int z){
...
}
double calculaSuma(int x, int y, int z){
...
}

Ejemplo

/* [Link] */

class Usuario4
{
String nombre;
int edad;
String direccion;

/* El constructor de la clase Usuario4 esta sobrecargado */


Usuario4( )
{
nombre = null;
edad = 0;
direccion = null;
}

Usuario4(String nombre, int edad, String direccion)

Programacion Java Página 37 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

{
[Link] = nombre;
[Link] = edad;
[Link] = direccion;
}

Usuario4(Usuario4 usr)
{
nombre = [Link]();
edad = [Link]();
direccion = [Link]();
}

void setNombre(String n)
{
nombre = n;
}

String getNombre()
{
return nombre;
}

/* El metodo setEdad() está sobrecargado */


void setEdad(int e)
{
edad = e;
}

void setEdad(float e)
{
edad = (int)e;
}

int getEdad()
{
return edad;
}

void setDireccion(String d)
{
direccion = d;
}

String getDireccion()
{
return direccion;
}
}

Ejemplo

/* [Link] */

Programacion Java Página 38 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

class ProgUsuario4
{
void imprimeUsuario(Usuario4 usr)
{
// [Link] equivale en este caso a [Link]()
[Link]("\nNombre: " + [Link] );
[Link]("Edad: " + [Link]() );
[Link]("Direccion: " + [Link]() +"\n");
}

public static void main(String args[])


{
ProgUsuario4 prog = new ProgUsuario4( );
/* Se declaran dos objetos de la clase Usuario4 */
Usuario4 usr1,usr2;

/* Se utiliza el constructor por omisión */


usr1 = new Usuario4( );
[Link](usr1);

/* Se utiliza el segundo constructor de Usuario4 */


usr2 = new Usuario4("Eduardo",24,"Mi direccion");
[Link](usr2);

/* Se utiliza el tercer constructor de Usuario4 */


usr1 = new Usuario4(usr2);

[Link](50);
[Link](30.45f);

[Link](usr1);
[Link](usr2);
}
}

Sobreescritura de métodos

Una subclase hereda todos los métodos de su superclase que son accesibles a dicha subclase a menos que la
subclase sobreescriba los métodos.

Una subclase sobreescribe un método de su superclase cuando define un método con las mismas
características ( nombre, número y tipo de argumentos) que el método de la superclase.

Las subclases emplean la sobreescritura de métodos la mayoría de las veces para agregar o modificar la
funcionalidad del método heredado de la clase padre.

Ejemplo

class ClaseA
{
void miMetodo(int var1, int var2)

Programacion Java Página 39 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

{ ... }

String miOtroMetodo( )
{ ... }
}

class ClaseB extends ClaseA


{
/* Estos métodos sobreescriben a los métodos
de la clase padre */

void miMetodo (int var1 ,int var2)


{ ... }

String miOtroMetodo( )
{ ... }
}

Clases abstractas

Una clase que declara la existencia de métodos pero no la implementación de dichos métodos (o sea, las
llaves { } y las sentencias entre ellas), se considera una clase abstracta.

Una clase abstracta puede contener métodos no-abstractos pero al menos uno de los métodos debe ser
declarado abstracto.

Para declarar una clase o un método como abstractos, se utiliza la palabra reservada abstract.

abstract class Drawing


{
abstract void miMetodo(int var1, int var2);
String miOtroMetodo( ){ ... }
}

Una clase abstracta no se puede instanciar pero si se puede heredar y las clases hijas serán las encargadas
de agregar la funcionalidad a los métodos abstractos. Si no lo hacen así, las clases hijas deben ser también
abstractas.

Control de acceso a miembros de una clase

Los modificadores más importantes desde el punto de vista del diseño de clases y objetos, son los que
permiten controlar la visibilidad y acceso a los métodos y variables que están dentro de una clase.

Uno de los beneficios de las clases, es que pueden proteger a sus variables y métodos (tanto de instancia
como de clase) del acceso desde otras clases.

Java soporta cuatro niveles de acceso a variables y métodos. En orden, del más público al menos público
son: público (public), protegido (protected), sin modificador (también conocido como package) y privado
(private).

Programacion Java Página 40 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

La siguiente tabla muestra el nivel de acceso permitido por cada modificador:

public protected (sin modificador) private


Clase SI SI SI SI
Subclase en SI SI SI NO
el mismo paquete
No-Subclase en SI SI SI NO
el mismo paquete
Subclase en SI SI/NO (*) NO NO
diferente paquete
No-Subclase en SI NO NO NO
diferente paquete
(Universo)

(*) Los miembros (variables y metodos) de clase (static) si son visibles. Los miembros de instancia no son
visibles.

Como se observa de la tabla anterior, una clase se ve a ella misma todo tipo de variables y métodos (desde
los public hasta los private); las demas clases del mismo paquete (ya sean subclases o no) tienen acceso a los
miembros desde los public hasta los sin-modificador. Las subclases de otros paquetes pueden ver los
miembros public y a los miembros protected, éstos últimos siempre que sean static ya de no ser así no serán
visibles en la subclase (Esto se explica en la siguiente página). El resto del universo de clases (que no sean ni
del mismo paquete ni subclases) pueden ver sólo los miembros public.

Interfaces
Una interface es una variante de una clase abstracta con la condición de que todos sus métodos deben ser
asbtractos. Si la interface va a tener atributos, éstos deben llevar las palabras reservadas static final y con un
valor inicial ya que funcionan como constantes por lo que, por convención, su nombre va en mayúsculas.

interface Nomina
{
public static final String EMPRESA = "Patito, S. A.";
public void detalleDeEmpleado(Nomina obj);
}

Una clase implementa una o más interfaces (separadas con comas ",") con la palabra reservada implements.
Con el uso de interfaces se puede "simular" la herencia múltiple que Java no soporta.

class Empleado implements Nomina


{
...
}

En este ejemplo, la clase Empleado tiene una clase padre llamada Object (implícitamente) e implementa a la
interface Nomina, quedando el diagrama de clases de la siguiente manera:

Programacion Java Página 41 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

La clase que implementa una interface tiene dos opciones:


1) Implementar todos los métodos de la interface.
2) Implementar sólo algunos de los métodos de la interface pero esa clase debe ser una clase abstracta
(debe declararse con la palabra abstract).

Programacion Java Página 42 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Laboratorio Modulo 4. Clases y Objetos en Java


Objetivo. Programar en Java programas solicitados basados en clases con sus respectivos métodos

1. Confeccionar una clase que represente un empleado. Definir como atributos su nombre y su
sueldo. Confeccionar los métodos para la carga, otro para imprimir sus datos y por último uno que
imprima un mensaje si debe pagar impuestos (si el sueldo supera a 3000)

2. Implementar la clase operaciones. Se deben cargar dos valores enteros, calcular su suma, resta,
multiplicación y división, cada una en un método, imprimir dichos resultados.

Programacion Java Página 43 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Módulo 5. Manejo de Excepciones y Recolección de Basura (Garbage


Collector)

Objetivo

Mostrar como utilizar el manejo de Excepciones y la invocación al Garbage Collector en Java

Introducción

Una excepción es un evento que ocurre durante la ejecución de un programa y detiene el flujo normal de la
secuencia de instrucciones de ese programa; en otras palabras, una excepción es una condición anormal que
surge en una secuencia de código durante su ejecución.

Las excepciones en Java están destinadas, al igual que en el resto de los lenguajes que las soportan, para la
detección y corrección de errores. Si hay un error, la aplicación no debería morirse y generar un core (o un
crash en caso del DOS). Se debería lanzar (throw) una excepción que a su vez debería capturar (catch) y
resolver la situación de error, o poder ser tratada finalmente (finally) por un gestor por defecto u omisión.
Java sigue el mismo modelo de excepciones que se utiliza en C++. Utilizadas en forma adecuada, las
excepciones aumentan en gran medida la robustez de las aplicaciones.

Excepciones
Las excepciones son la manera que ofrece Java de manejar los errores en tiempo de ejecución. Muchos
lenguajes imperativos, cuando tenían un error de este clase lo que hacían era detener la ejecución del
programa. Las excepciones nos permiten escribir código que nos permita manejar ese error y continuar (si lo
estimamos conveniente) con la ejecución del programa.

El error en ejecución más clásico en Java es el de desbordamiento. Es decir, el intento de acceso a una
posición de un vector que no existe. Por ejemplo:

[Link]
public class Desbordamiento {
static String mensajes[] = {"Primero", "Segundo", "Tercero" };
public static void main(String[] args) {
for (int i=0; i<=3; i++)
[Link](mensajes[i]);
[Link]("Ha finalizado la ejecución");
}
}

Este programa tendrá un serio problema cuando intente acceder a mensajes[3], pues no existe dicho valor.
Al ejecutarlo nos dirá lo siguiente (o algo parecido):

Primero

Segundo

Tercero

Programacion Java Página 44 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Exception in thread "main" [Link]

at [Link]([Link], Compiled Code)

Nos da un error de ejecución (en esta terminología se diría que se lanzó una excepción) al intentar acceder a
dicho valor inexistente. Vemos que, por ahora, el comportamiento de nuestro código es el mismo que en los
lenguajes imperativos. Cuando encuentra el error, se para la ejecución. Ahora veremos cómo evitar esto.

Try...Catch...finally
Existe una estructura que nos permitirá capturar excepciones, es decir, reaccionar a un error de ejecución.
De este modo podremos imprimir mensajes de error "a la medida" y continuar con la ejecución del
programa si consideramos que el error no es demasiado grave. Para ver cómo funcionan vamos a modificar
el ejemplo anterior, pero asegurándonos ahora de que capturamos las excepciones:

[Link]

public class NuestroPrimerCatch {


static String mensajes[] = {"Primero", "Segundo", "Tercero" };
public static void main(String[] args) {
try {
for (int i=0; i&lt;=3; i++)
[Link](mensajes[i]);
}
catch ( ArrayIndexOutOfBoundsException e ) {
[Link]("El asunto se nos ha desbordado");
}
finally {
[Link]("Ha finalizado la ejecución");
}
}
}

Dentro del bloque que sigue a try colocamos el código a ejecutar. Es como si dijeramos que vamos a intentar
ejecutar dicho código a ver qué pasa. Después de try deberemos colocar al menos un bloque catch o un
bloque finally, pudiendo tener ambos e incluso más de un bloque catch.

En el bloque finally ponemos el código que se ejecutará siempre, tanto si se lanza la excepción como si no.
Su utilidad no es mucha, ya que si se permite continuar con la ejecución del programa basta con poner el
código después del bloque try...catch. En nuestro ejemplo podríamos haber puesto lo siguiente:

try {
for (int i=0; i<=3; i++)
[Link](mensajes[i]);
}
catch ( ArrayIndexOutOfBoundsException e ) {
[Link]("El asunto se nos ha desbordado");
}
[Link]("Ha finalizado la ejecución");

Y habría funcionado exactamente igual. La miga está en los bloques catch.

Programacion Java Página 45 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Clase Exception

Cuando se lanza una excepción, en nuestro mundo orientado objetos lo que se hace es lanzar una instancia
de Exception o de una clase derivada de él. Normalmente las clases derivadas no añaden mucha
funcionalidad (muchas veces ninguna en absoluto), pero al ser distintas nos permiten distinguir entre los
distintos tipos de excepciones.

En el programa anterior, por ejemplo, en el bloque catch capturábamos una excepción del tipo
ArrayIndexOutOfBoundsException, ignorando cualquier otro tipo de excepción.

Esta clase tiene como cositas interesantes dos constructores y dos métodos (tiene más métodos pero sólo
vamos a ver éstos):

Exception e = new Exception()

Exception e = new Exception ( String )

String [Link]()

void [Link]()

Capturar excepciones

Ahora sabemos lo suficiente como para entender cómo funcionan los catch. Entre paréntesis, cual
parámetro se pone la declaración de una excepción, es decir, el nombre de una clase derivada de Exception
(o la misma Exception) seguido por el nombre de la variable. Si se lanza una excepción que es la que
deseamos capturar o una derivada de la misma se ejecutará el código que contiene el bloque. Así, por
ejemplo:

catch (Exception e) {

...

Se ejecutará siempre que se produzca una excepción del tipo que sea, ya que todas las excepciones se
derivan de Exception. No es recomendable utilizar algo así ya que estamos capturando cualquier tipo de
excepciones sin saber si eso afectará a la ejecución del programa o no.

Se pueden colocar varios bloques catch. En ese caso, se comprobará en orden si la excepción lanzada es la
que deseamos capturar y si no pasa a comprobar la siguiente. Eso sí, sólo se ejecuta un bloque catch. En
cuanto captura la excepción deja de comprobar los demás bloques. Por eso, lo siguiente:

catch (Exception e) {

...

catch (DerivadaDeException e) {

Programacion Java Página 46 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

...

Daría error, ya que el segundo bloque no podría ejecutarse nunca.

Excepciones Predefinidas

Las excepciones predefinidas y su jerarquía de clases es la que se muestra en la figura:

Los nombres de las excepciones indican la condición de error que representan. Las siguientes son las
excepciones predefinidas más frecuentes que se pueden encontrar:

ArithmeticException

Las excepciones aritméticas son típicamente el resultado de una división por 0:

int i = 12 / 0;

NullPointerException

Programacion Java Página 47 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Se produce cuando se intenta acceder a una variable o método antes de ser definido:

class Hola extends Applet {

Image img;

paint( Graphics g ) {

[Link]( img,25,25,this );

IncompatibleClassChangeException

El intento de cambiar una clase afectada por referencias en otros objetos, específicamente cuando esos
objetos todavía no han sido recompilados.

ClassCastException

El intento de convertir un objeto a otra clase que no es válida.

y = (Prueba)x; // donde

x no es de tipo Prueba

NegativeArraySizeException

Puede ocurrir si hay un error aritmético al intentar cambiar el tamaño de un array.

OutOfMemoryException

¡No debería producirse nunca! El intento de crear un objeto con el operador new ha fallado por falta de
memoria. Y siempre tendría que haber memoria suficiente porque el garbage collector se encarga de
proporcionarla al ir liberando objetos que no se usan y devolviendo memoria al sistema.

NoClassDefFoundException

Se referenció una clase que el sistema es incapaz de encontrar.

ArrayIndexOutOfBoundsException

Es la excepción que más frecuentemente se produce. Se genera al intentar acceder a un elemento de un


array más allá de los límites definidos inicialmente para ese array.

UnsatisfiedLinkException

Se hizo el intento de acceder a un método nativo que no existe. Aquí no existe un método [Link]

class A {

native void kk();

InternalException

Programacion Java Página 48 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Este error se reserva para eventos que no deberían ocurrir. Por definición, el usuario nunca debería ver este
error y esta excepción no debería lanzarse.

Generar Excepciones

Cuando se produce un error se debería generar, o lanzar, una excepción. Para que un método en Java,
pueda lanzar excepciones, hay que indicarlo expresamente.

void MetodoAsesino() throws NullPointerException,CaidaException

Se pueden definir excepciones propias, no hay por qué limitarse a las predefinidas; bastará con extender la
clase Exception y proporcionar la funcionalidad extra que requiera el tratamiento de esa excepción.

También pueden producirse excepciones no de forma explícita como en el caso anterior, sino de forma
implícita cuando se realiza alguna acción ilegal o no válida.

Las excepciones, pues, pueden originarse de dos modos: el programa hace algo ilegal (caso normal), o el
programa explícitamente genera una excepción ejecutando la sentencia throw (caso menos normal). La
sentencia throw tiene la siguiente forma:

throw ObtejoExcepction;

El objeto ObjetoException es un objeto de una clase que extiende la clase Exception .

El siguiente código de ejemplo origina una excepción de división por cero:

class melon {

public static void main( String[] a ) {

int i=0, j=0, k;

k = i/j; // Origina un error de division-by-zero

Si compilamos y ejecutamos esta aplicación Java, obtendremos la siguiente salida por pantalla:

> javac [Link]

> java melon

[Link]: / by zero

at [Link]([Link])

Las excepciones predefinidas, como ArithmeticException , se conocen como excepciones runtime.


Actualmente, como todas las excepciones son eventos runtime, sería mejor llamarlas excepciones
irrecuperables. Esto contrasta con las excepciones que generamos explícitamente, que suelen ser mucho
menos severas y en la mayoría de los casos podemos recuperarnos de ellas. Por ejemplo, si un fichero no
puede abrirse, preguntamos al usuario que nos indique otro fichero; o si una estructura de datos se
encuentra completa, podremos sobreescribir algún elemento que ya no se necesite.

Programacion Java Página 49 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

El Recolector de Basura ( Garbage Collector)

Una de los aportes más relevantes de Java es la inclusión del recolector de basura ( garbage collector) tanto
que hoy en día es un estándar y ni se menciona como una característica del lenguaje. Java no lo inventó,
pero si aportó mucho para su adopción.

El GC corre automáticamente en la JVM cada cierto tiempo. No hay forma de proveer cuando lo hará (o si lo
hará) ni de forzar a que corra (o que no lo haga). Existen varias estrategias de implementación y es todo un
tema que sigue en desarrollo e investigación. Lo mejor de todo es que como usuarios de la plataforma
tenemos muy poco que hacer para utilizarlo.

Referencias

La regla para que un objeto pueda ser recolectado es sencilla, no debe de haber referencias al objeto.

....
Empleado a = new Empleado("God"); // a es la 1ra referencia
Empleado b = a; // b es la segunda referencia al mismo objeto "God"
...

En el ejemplo anterior se creó un objeto de tipo Empleado y hay dos referencias a él (a y b). Este objeto no
será recolectado por el gc y su memoria seguirá en uso.

Cuando ya no hay referencias al objeto:

a = new Empleado("inez"); // "a" ahora apunta a otro objeto solo queda una: b
b = null; // b ahora no apunta a nada, ya no quedan referencias al objeto "God"

Entonces el espacio de memoria de nuestro primer empleado puede ser reclamado por el gc y liberado.

Cuando se trata de variables creadas en un método ( ya sea en el cuerpo o en los parámetros ) las
referencias se limpian al terminar la ejecución del método.

Ejemplo

Un ejemplo muy ilustrador del uso de memoria, del garbage collector y los memory leaks es la siguiente
implementación de una pila.

class Stack {

private int index = -1;


private Object [] data = new Object[10]; // un espacio para 10 elementos

/** Agrega el elemento a la pila */


public void push( Object o ) {
checkUpperLimit();
data[++index] = o;
}

/** Devuelve el elemento que está en el tope de la pila */


public Object peek() {
datos[index];

Programacion Java Página 50 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

}
/** Devuelve el elemento del tope de la pila */
public Object pop() {
checkLowerLimit();
data[index--];
}

// metodos auxiliares no relevantes en este momento....


private void checkUpperLimit() { checkLimits(index+1);}
private void checkLowerLimit() { checkLimits(index-1);}
private void checkLimits( int futureValueOfIndex ) {
if ( futureValueOfIndex >= [Link] ) { throw new RuntimeException("StackOverflow :-o "); }
if ( futureValueOfIndex < -1 ) { throw new RuntimeException("StackUnderflow :-S"); }
}

Puedes identificar la fuga de memoria? No?

La fuga se encuentra en el método pop().

La implementación es sencilla. Un arreglo y un indice para saber en donde está el tope.

 Con push() Se incrementa el indice y se pone el elemento ahí.


 Con peek() Se devuelve el elemento al que esté señalando el índice
 Con pop( ) Se devuelve el elemento señalado y después de decrementa el indice.

Lo malo es que pop solamente decrementa el apuntador, pero lo que se haya almacenado ahí, sigue ahí. Si
se pone un objeto y luego este objeto se elimina, y el buen programador se encarga de eliminar todas las
referencias, el gc no podrá hacer su trabajo por que aún existe una referencia en el arreglo. Solamente se
perderá hasta que otro objeto ocupe ese espacio, pero mientras tanto el objeto ahí queda inaccesible y no
reclamable.

....
public void produce() {
Request request = [Link]();
[Link]( request ); // 2 referencias al objeto request...
}
public void consume() {
RequestExecutor executor = ...
[Link]( [Link]() ); // deja un request en la memoria interna del stack que no puede ser
reclamable
}
...

Para arreglarlo hay que eliminar la referencia y listo.

...
public void pop() {
Object value = peek();
checkLowerLimit();
data[index--] = null; // eliminamos la referencia y decrementamos el indice
return value;

Programacion Java Página 51 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Se crea una referencia "value" pero esta se pierde al terminar el método. La referencia que estaba dentro
del arreglo se pierde también al apuntarlo a otro lado ( null en este caso ) y no más memory leaks.

Programacion Java Página 52 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Laboratorio Modulo 5. Gestión de Excepciones

Objetivo. Generar la captura de excepciones de una aplicación de Java y generar las propias

1. Escriba código para generar y capturar una excepción ArrayIndexOutOfBoundsException (Índice de


matriz fuera de límites).

2. Cree su propia clase de excepción utilizando la palabra clave extends. Escriba un constructor para dicha
clase que tome un argumento String y lo almacene dentro del objeto como una referencia de tipo String.
Escriba un método que muestre la cadena de caracteres almacenada. Cree una cláusula try-catch para
probar la nueva excepción.

Programacion Java Página 53 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Módulo 6. Implementación de Objetos del Paquete Java Lang

Objetivo
Mostrar como utilizar algunas de los objetos mas utilizados dentro del paquete [Link] que ofrece el
lenguaje de Java

Introducción
Antes de nada queremos recordar que el paquete [Link] se importa automáticamente. Esto quiere decir
que no es necesario poner en la clase donde se vaya a hacer uso de este paquete la cláusula o instrucción
correspondiente “import [Link]”. Dentro de este paquete están gran parte de las clases más utilizadas
dentro de las aplicaciones o programas creados con tecnología Java.

Clases del paquete [Link]


Para ver lo anteriormente comentado hemos creado un ejemplo de código muy básico, como el siguiente:

public class Programa {

public static void main(String arg[]) {

String cadena = new String("El paquete java lang se importa automáticamente.");

[Link](cadena);

onde vemos que en el código del Programa no ha sido necesario hacer uso de la clausula import [Link]
para poder utilizar la clase String. Obtenemos la siguiente salida:

Ahora vamos a proceder a repasar muy rápidamente un poco tanto las interfaces, como las clases
principales del paquete, así como las posibles excepciones y errores que se pueden producir. En los
siguientes epígrafes haremos un repaso rápido y teórico para luego hacer ejercicios y ejemplos.

Interfaces

Programacion Java Página 54 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Las interfaces que consideramos principales del paquete [Link] son las siguientes:

 Cloneable
 Comparable
 Iterable

Estas 3 interfaces nos definen los métodos necesarios a definir en nuestra clase para que puedan
implementar dicha interfaz. Por un lado la interfaz Cloneable nos obliga a implementar el método
denominado clone() que aparece en la clase Object y que sirve para crear una copia o clon de un objeto.

Comparable <K> nos obliga a implementar el método cuya cabecera es la siguiente:

int compareTo(claseK objeton)

Y que lo que debe hacer es comparar 2 objetos de la misma clase claseK y se debe devolver -1, 0 o 1 si el
objeto que llama al método es respectivamente menor, igual o mayor que el objeto especificado en el
método por objeton.

Por último la interfaz Iterable <T> nos obligaría a definir el método siguiente:

Iterator<T> iterator()

Donde deberemos de devolver un iterador sobre el conjunto de elementos de tipo T. Un iterador es un


objeto de una clase que implementa la interfaz Iterator y que obliga a implementar 3 métodos:

public boolean hasNext();

public Object next();

public void remove();

Clases
En cuanto a lo que respecta a clases, todas son casi imprescindibles de conocer, ya que son básicas y por
eso están en el paquete [Link] pero vamos a destacar unas cuantas por considerarlas principales.

PRINCIPALES CLASES EN EL PAQUETE [Link]

Boolean Math

Double String

Float StringBuffer

Integer System

Boolean
La clase Boolean ya la conocemos. Es lo que se llama un wrap o envoltorio, que es una clase que permite
manejar los datos equivalentes de tipo primitivo. En este caso la clase Boolean es un wrap del tipo primitivo

Programacion Java Página 55 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

boolean. Los métodos de esta clase permiten el manejo de los valores primitivos true o false, su
modificación o su comparación ya que implementa la interfaz Comparable.

Double
Es la clase wrap correspondiente al tipo primitivo double, por lo que lo métodos son muy parecidos a los de
la clase Boolean, pero manejando los tipos primitivos para double. Permitiendo obtener, modificar,
comparar, etc valores de tipo double.

Float
Al igual que las anteriores también es un wrap pero para el tipo básico o primitivo float.

Integer
Esta es quizás la clase de todos los wrappers más utilizada con diferencia y por tanto maneja tipos primitivos
de tipo int. Tiene una gran cantidad de métodos sobre todo para poder convertir el entero a otros tipos
como long, float, double, etc.

Math
La clase Math tiene una gran cantidad de métodos para poder hacer operaciones matemáticas, como las
funciones sin (double a) que calcula el seno del valor a, tan (double a) que calcula la tangente de a, etc.

String
La clase String, quizás hasta más utilizada que la Integer, es una clase que permite la definición y manejo de
cadenas de caracteres. Pero un inconveniente posible es que se define como constante y tras su creación no
puede ser cambiada (se dice que es inmutable, como explicaremos más adelante).

Por ejemplo si quisiéramos tener una cadena con valores “abc” bastaría con definir una variable de la Clase
String de la siguiente manera:

String str = "abc";

Esto automáticamente es correcto aunque quizás fuera más formal lo siguiente:

char data[] = {'a', 'b', 'c'};

String str = new String(data);

La amplia funcionalidad y manejo de String se puede ver en la gran cantidad de métodos que disponemos
en esta clase para su manejo, donde podemos hacer comparaciones entre cadenas, comparaciones
ignorando mayúsculas (muy útil cuando por ejemplo queremos comparar si la contraseña de un usuario es
la correcta), concatenación de cadenas, consulta de carácter en una posición determinada de la cadena,
reemplazar caracteres, convertir a mayúsculas, o minúsculas, etc.

Concepto de inmutabilidad
Veamos el significado de inmutable, que no es precisamente sencillo de explicar. Consideremos que un
objeto ocupa un espacio de memoria. Ahora diremos que hay dos tipos de objetos:

Programacion Java Página 56 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

a) Objetos mutables: son aquellos cuyo espacio de memoria puede ser reemplazado por un contenido
definido con posterioridad a la creación del objeto. En este caso, cuando usamos métodos
modificadores es el objeto original el que sufre el cambio

b) Objetos inmutables: son aquellos cuyo espacio de memoria permanece ocupado con el objeto tal y
como se creó inicialmente. ¿Significa esto que no podemos usar métodos modificadores? No, no
significa eso. Significa que cuando usamos métodos modificadores en vez de redefinirse el objeto
original, la variable apuntadora pasa a apuntar a un nuevo objeto que se crea, permaneciendo el
original en su espacio de memoria, podemos decir que en algunos casos “inaccesible”, pero
estando.

En Java, la mayoría de los objetos "esenciales" son inmutables: Long, Integer, Boolean, String, , etc. Un
objeto se considera inmutable si su estado no puede cambiarse luego de ser construido. Este
comportamiento está ampliamente aceptado como una estrategia robusta para crear código simple y
confiable. La inmutabilidad se considera efectiva en aplicaciones concurrentes (hablamos de concurrencia
para referirnos a dos tareas que transcurren durante el mismo intervalo de tiempo) donde la mutabilidad
(cambiar los objetos su estado), podría dar lugar a que los objetos se corrompieran o llegaran a tener un
estado inconsistente.

Nosotros en principio no debemos preocuparnos por el costo de crear nuevos objetos frente a actualizar el
mismo objeto. En general usar objetos inmutables es eficiente y solo en casos muy específicos tendríamos
que preocuparnos por soluciones que ahorraran la multiplicación de objetos.

Aunque no “nos preocupemos” por ella, sí es deseable que tengamos el concepto de inmutabilidad claro.

Stringbuffer

Es una versión mejorada o ampliada de la clase String, ya que permite su modificación después de su
creación, es decir, los objetos de tipo StringBuffer son objeto mutables. El método más utilizado de esta
clase es insert, que permite insertar cualquier objeto de cualquier tipo como String a la secuencia de
StringBuffer.

System

Por último la clase System es una de las clases más usuales. Define tres campos err, in y out que
respectivamente son la salida estándar de error, entrada estándar y salida estándar. Los métodos para el
manejo de estas entradas y salidas estándares de datos son bastante utilizados, al igual que el método
currentTimeMillis() que devuelve la fecha actual en milisegundos. También es muy usual el uso del
métodogetenv() para acceder a variables de entorno o propiedades del sistema. Cuando se invoca este
método, se nos devuelve información sobre el sistema con que estamos trabajando.

Excepciones

Aunque más adelante trataremos el uso y gestión de excepciones, queremos mencionar las más usuales de
este paquete. Adelantar que una excepción se produce cuando ocurre un evento, un cálculo, o una
ejecución de una instrucción falla produciéndose un problema por el que esa instrucción, cálculo o evento
no se puede realizar.

Así las más típicas excepciones pueden ser las siguientes:

 ArithmeticException: se produce cuando hay un problema aritmético, como por ejemplo una
división por cero.

Programacion Java Página 57 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

 ArrayIndexOutOfBoundsException: producida cuando queremos acceder a un array con un índice


fuera de su rango.
 Exception: es la clase principal de todas las excepciones y de ellan cuelgan todas.
 NullPointException: normalmente producida cuando intentamos acceder a un objeto que está
apuntando a null.
 RunTimeException: Es una excepción producida en tiempo de ejecución del programa, por tanto si
queremos crear nuestras propias excepciones posiblemente debamos de crear nuestra clase
heredando de esta.

Programacion Java Página 58 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Modulo 7. GUI de Java

Objetivo

Mostrar como crear aplicaciones en Java que tengan una interfaz grafica por medio de las librerías AWT y
SWING

Introducción
Java incluye como parte de su biblioteca de clases estándar un conjunto de componentes para crear
interfaces gráficas de usuario, los cuales permiten crear interfaces portables.

AWT Y SWING
Los componentes que se utilizan en Java para crear interfaces gráficas de usuario se agrupan en dos
paquetes :

[Link] (Abstract Window Toolkit)

Los componentes awt dependen de las facilidades gráficas ofrecidas por cada sistema operativo : los
programas escritos con AWT tendrán un « look and feel » distinto en windows y en UNIX.

[Link]

SWING es 100% java y por tanto es independiente de la plataforma, los componentes gráficos se pintan en
tiempo de ejecución por lo que las aplicaciones SWING suelen ser más lentas que las de AWT.

En la práctica las aplicaciones Java con interfaces gráficas de usuario suelen mezclar AWT y SWING, asi AWT
se encarga de toda la gestión de eventos y SWING ofrece componentes más sofisticados.

Frames
Los frames o marcos son ventanas en las que se pueden colocar otros controles de los que se utilizan para
crear las intefaces gráficas de usuario (botones, etiquetas, cajas de texto, listas desplegables, menús, etc).
Los frames son ventanas que puede tener borde y barra de título con botones de maximizar / minimizar /
cerrar

AWT SWING

[Link] [Link]

Resultado usando la librería SWING

Programacion Java Página 59 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Manejo de Eventos

Cada vez que el usuario teclea un caracter o pulsa un botón del ratón, ocurre un evento. Todo lo que tiene
que hacer es implementar el interface apropiado y ser registrado como un oyente de evento del evento
fuente apropiado. Los componentes Swing puede generar muchas clases de evento.

Aquí hay unos pocos ejemplos.

Acción que resulta en el evento Tipo de oyente


El usuario pulsa un botón, presiona Return mientras teclea en un campo de texto, ActionListener
o elige un ítem de menú.
El usuario elige un frame (ventana principal). WindowListener
El usuario pulsa un botón del ratón mientras el cursor está sobre un componente. MouseListener
El usuario mueve el cursor sobre un componente. MouseMotionListener
El componente se hace visible. ComponentListener
El componente obtiene obtiene el foco del teclado. FocusListener
Cambia la tabla o la selección de una lista. ListSelectionListener

Cómo Implementar un Manejador de Eventos

Todo manejador de eventos requiere tres partes de código.

1. Donde se declare la clase del manejador de eventos, el código especifica que la clase o implementa
un interface de oyente, o desciende una clase que implementa un interface de oyente. Por
ejemplo.

public class MyClass implements ActionListener {

2. El código que registra un ejemplar de la clase de manejo de eventos de un oyeNte sobre uno o más
componentes. Por ejemplo.

[Link](instanceOfMyClass);

Programacion Java Página 60 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

3. La implementación de los métodos del interface oyente. Por ejemplo.

public void actionPerformed(ActionEvent e) {

...//code that reacts to the action...

Un escenario de manejo de eventos típico ocurre con los botones (JButton). Para detectar cuando el usuario
pulsa un botón de la pantalla (o pulsa la tecla equivalente), un programa debe tener un objeto que
implementa el interface ActionListener.

El programa debe registrar este objeto como un oyente de actión del botón (la fuente del evento), usando el
método addActionListener. Cuando el usuario pulsa el botón de la pantalla, éste dispara el evento action,
Esto resulta en una llamada al método actionPerformed del oyente de action, el único método del interface
ActionListener). El único argumento del método es un objeto ActionEvent que ofrece información sobre el
evento y su fuente.

ActionEvent

button -----------------------------------> action listener

Programacion Java Página 61 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Reglas Generales del Uso de Componentes

El paquete Swing define dos tipos de componentes.

 Contenedores de alto nivel (JFrame, JApplet, JWindow, JDialog)

 Componentes de peso ligero (Jcualquier-cosa, como JButton, JPanel, y JMenu)

Los contenedores de alto nivel proporcionan el marco de trabajo en el que existen los componentes de
peso ligero. Específicamente, un contenedor de alto nivel Swing proporciona un área en el que los
componentes de peso ligero Swing pueden dibujarse a sí mismos. Los contenedores de alto nivel Swing
también proporcionan otras características Swing como el espacio para una barra de menú, manejo
avanzado de eventos y dibujo, y soporte de accesibilidad.

En general, todo componente Swing debería tener un contenedor Swing de alto nivel por encima en el árbol
de contenidos. Por ejemplo, todo applet que contenga componentes Swing debería estar implementado
como una subclase de JApplet (que es una subclase de Applet). De forma similar, toda ventana principal que
contenga componentes Swing debería ser implementada con un JFrame.

Aquí tenemos una imagen del árbol de contenido de un GUI de un típico programa Swing que implementa
una ventana que contiene dos botones, un campo de texto y una lista.

El panel de contenido de las figuras anteriores es el Contenedor normal que hay debajo de cada contenedor
Swing.

Aquí está el código que construye el GUI mostrado en las figuras anteriores.

JPanel panel = new JPanel();


[Link](new SomeLayoutManager());
[Link](textField);
[Link](list);
//topLevel es un ejemplar de JApplet o JFrame
Container contentPane = [Link]();
[Link](new AnotherLayoutManager());

Programacion Java Página 62 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

[Link](button1);
[Link](button2);
[Link](panel);

Crear y configurar un Frame

Método Propósito

JFrame() Crea un frame. El argumento String proporciona el título del frame.

JFrame(String)

void Selecciona u obtiene la operación que ocurre cuando el usuario pulsa el


setDefaultCloseOperation(int) botón de cerrar la ventana. Las posibles elecciones son.

int getDefaultCloseOperation()  DO_NOTHING_ON_CLOSE

 HIDE_ON_CLOSE (por defecto)

 DISPOSE_ON_CLOSE

Estas constantes están definidas en el interface WindowConstants.

Miremos el primer ejemplo « [Link]« sólo con swing

//Importar el paquete swing


import [Link].*;
public class HelloWorldSwing {
private static void createAndShowGUI() {
//Configurar la decoración del frame
[Link](true);
//Crear y configurar el cierre del contenedor.
JFrame frame = new JFrame("HelloWorldSwing");
[Link](JFrame.EXIT_ON_CLOSE);
//Construir el label y adherirlo al contenedor.
JLabel label = new JLabel("Hello World");
[Link]().add(label);
//Desplegar la ventana.
[Link]();
[Link](true);
}
public static void main(String[] args) {
[Link](new Runnable() {
public void run() {
createAndShowGUI();
}
});
}

Programacion Java Página 63 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Existen diferentes formas de instanciar el Jframe, veamos otros ejemplos de hola mundo con swing y awt :

En el siguiente ejemplo la clase que hereda de JFrame, en ella se crea una instancia de JFrame, se configura
y se muestra; todo el código va incluido dentro del método main() (único método de la clase).

// VENTANA SENCILLA A PARTIR DE JFRAME


import [Link].*;
import [Link].*;
// CLASE PRINCIPAL DEL PROGRAMA (hereda de JFrame)
public class Ventana_sencilla extends JFrame {
// MÉTODO DE ENTRADA AL PROGRAMA
public static void main(String args[]) {
// crear y configurar la ventana
JFrame frame = new JFrame("Ventana desde JFrame");

// acción por defecto al cerrar la ventana: salir del programa


[Link](JFrame.EXIT_ON_CLOSE);
JPanel panel1 = new JPanel();
// para añadir un panel a un JFrame
[Link]().add(panel1);
// mostrar la ventana
[Link](340,240); // dimensiones
[Link](200,200); // posición
[Link](false); // no cambia el tamaño
[Link](true); // mostrarla
}
}

En este otro ejemplo la clase que hereda de JFrame, con un método constructor de la propia clase que es el
que crea y muestra la ventana, el método main() simplemente instancia un ejemplar de la clase.

// VENTANA SENCILLA A PARTIR DE UN JFRAME


import [Link].*;
import [Link].*;
// CLASE PRINCIPAL DEL PROGRAMA (hereda de JFrame)
public class Ventana_sencilla extends JFrame {
// variables a nivel de clase
private JPanel panel1;
// MÉTODO DE ENTRADA AL PROGRAMA
public static void main(String args[]) {
// instancia de la clase principal
new Ventana_sencilla();
}
// MÉTODO CONSTRUCTOR QUE CREA Y MUESTRA LA INTERFAZ
// Ventana_sencilla hereda las características de JFrame
public Ventana_sencilla() {
/* la variable especial this se usa en métodos de instancia
* para hacer referencia al objeto que contiene al método,
* aquí equivale a JFrame */

Programacion Java Página 64 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

// acción por defecto al cerrar la ventana: salir del programa


[Link](JFrame.EXIT_ON_CLOSE);
// la ventana
[Link]("Ventana desde JFrame");
[Link](340, 240);
[Link](200,200);
[Link](false);
[Link](true);
}
}

La salida para ambos ejemplos será una Ventana como la que se muestra a continuación en la imagen

Ejemplos Varios de Aplicacion de elementos de SWING

Ejemplo 1. Hola Mundo con la función paint() : [Link]

//Se importan las librerías


import [Link].*;
import [Link].*;
//La clase hereda de JFrame
public class HolaMundoAplicacionSwing extends JFrame
{
//Constructor
public HolaMundoAplicacionSwing(String titulo)
{
//Se invoca al constructor de JFrame que recibe el titulo como parámetro
super(titulo);
}
public static void main(String ar[])
{
HolaMundoAplicacionSwing sw = new HolaMundoAplicacionSwing("HOLA CON SWING !!");

Programacion Java Página 65 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

// acción por defecto al cerrar la ventana: salir del programa


[Link](JFrame.EXIT_ON_CLOSE);

[Link](300, 300);
[Link](true);
}

//Función paint de awt


public void paint(Graphics g)
{
setBackground([Link]);
[Link]([Link]);
[Link]("HOLA MUNDO !!", 50, 50);
}
}

Ejemplo 2 : DosBotones con campo de texto y ventana

//Se importan las librerias


import [Link].*;
import [Link].*;
import [Link].*;
//Esta clase hereda de JPanel
public class DosBotones extends JPanel {

//Se declaran los dos botones y el campo de texto


JButton boton1 = new JButton( "JButton 1" );
JButton boton2 = new JButton( "JButton 2" );
JTextField texto = new JTextField( 20 );

//Constructor de la clase
public DosBotones() {

ActionListener al = new ActionListener() {


public void actionPerformed( ActionEvent evt ) {
String nombre = ( (JButton)[Link]()).getText();
[Link]( nombre+" Pulsado" );
}
};

[Link]( al );
[Link]( "Soy el JBoton 1" );

Programacion Java Página 66 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

add( boton1 );
[Link]( al );
[Link]( "Soy el JBoton 2" );
add( boton2 );
[Link]( "Soy el JCampoDeTexto" );
add( texto );
}

public static void main( String args[] ) {

//Se declara el frame


JFrame ventana = new JFrame( "Tutorial de Java, Swing" );

[Link]( new WindowAdapter() {


//Para cerrarse correctamente
public void windowClosing( WindowEvent evt ){
[Link]( 0 );
}
}
);

// Se adiciona el panel a el frame


[Link]().add( new DosBotones(),[Link] );
[Link]( 300,100 );

[Link]( true );
}
}

Ejemplo 3 : [Link]

// Se importan las librerias


import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
//La clase hereda de JFrame e implementa la interfaz ActionListener
public class AplicacionDatosSwingSetVisible extends JFrame
implements ActionListener{

//Labels y textos de entrada de datos: nombre, carnet y pago


JLabel lno, lca,lpa, entrada;
JTextField tno, tca, tpa;

//Labels y textos de salida de datos: nombre, carnet y pago


JLabel sno, sca, spa, salida;
JTextField tsno, tspa, tsca;
//Boton para mostrar los datos de salida
JButton b;
//Constructor

Programacion Java Página 67 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

public AplicacionDatosSwingSetVisible( String titulo)


{
//Se invoca el constructor del padre (JFrame) el cual recibe el titulo del frame
super(titulo);

getContentPane().setLayout(new FlowLayout());

lno = new JLabel("Digite sus nombres: ");


lca = new JLabel("Carnet: ");
lpa = new JLabel("Pago: ");
entrada = new JLabel("Entrada De Datos: ");

tno = new JTextField(20);


tca = new JTextField(10);
tpa = new JTextField(10);

salida = new JLabel("Datos Digitados");


sno = new JLabel("Nombres: "); tsno = new JTextField(30);
sca = new JLabel("Carnet: "); tsca = new JTextField(10);
spa = new JLabel("Pago: "); tspa = new JTextField(10);
b = new JButton("Mostrar");
[Link](this);

getContentPane().add(entrada);
getContentPane().add(lno);
getContentPane().add(tno);
getContentPane().add(lca);
getContentPane().add(tca);
getContentPane().add(lpa);
getContentPane().add(tpa);
getContentPane().add(b);
getContentPane().add(salida);
getContentPane().add(sno);
getContentPane().add(tsno);
getContentPane().add(sca);
getContentPane().add(tsca);
getContentPane().add(spa);
getContentPane().add(tspa);

[Link](false);
[Link](false);
[Link](false);
[Link](false);
[Link](false);
[Link](false);
// acción por defecto al cerrar la ventana: salir del programa
[Link](JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e)
{
String nombres = [Link]();
[Link](nombres);

Programacion Java Página 68 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

String carnet = [Link]();


[Link](carnet);
String pago = [Link]();
[Link](pago);

//Hacemos visibles las componentes de salida


// Con sus contenidos
[Link](true);
[Link](true);
[Link](true);
[Link](true);
[Link](true);
[Link](true);

[Link]("");
[Link]("");
[Link]("");
}
public static void main(String ar[])
{
AplicacionDatosSwingSetVisible fr =
new AplicacionDatosSwingSetVisible("Entrada Swing");
[Link](1000, 300);
[Link](true);

}
}

Ejemplo 4 : [Link]

// Se importan las librerias


import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
//La clase hereda de JFrame e implementa la interfaz ActionListener
public class InterfaceGrafica
extends JFrame
implements ActionListener {

//Se definen los componentes de la interfaz como privados


private JLabel l;
private JTextField t;
private JButton b1, b2;

//Constructor de la clase
public InterfaceGrafica( String titulo)
{
//Se invoca el constructor del padre (JFrame) el cual recibe el titulo del frame
super(titulo);

Programacion Java Página 69 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

getContentPane().setLayout(new FlowLayout());

// Se inicializan los datos miembros de la clase


l = new JLabel("");
t = new JTextField(20);
b1 = new JButton("Boton para ver Hola mundo");
b2 = new JButton("Boton para ver contenido");

// Se adhieren los componentes al panel raíz


getContentPane().add(t);
getContentPane().add(b2);
getContentPane().add(b1);
getContentPane().add(l);
//Se define cual de los elementos son visibles
[Link](false);
[Link](true);
[Link](true);
[Link](true);

// acción por defecto al cerrar la ventana: salir del programa


[Link](JFrame.EXIT_ON_CLOSE);

//Se adiciona al listener el componente que va a generar eventos


[Link](this);
[Link](this);
}
//Se define la acción a desarrollar cuando se genere un evento
public void actionPerformed(ActionEvent e)
{

if([Link]() == b1){
[Link]("Hola Mundo");
[Link](true);
}

if([Link]() == b2){
[Link]([Link]());
[Link](true);
}

}
//Función principal
public static void main(String ar[])
{
//Se instancia la clase
InterfaceGrafica gui = new InterfaceGrafica ("Hola Mundo Swing");
[Link](1000, 300);
[Link](true);

}
}

Programacion Java Página 70 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Laboratorio Modulo 7. GUI de Java


Objetivo. Crear una aplicación de Java que tenga una interfaz gráfica según lo requerido.

1. Genera un programa de conversión de temperaturas entre Fahrenheit y Centígrados, utilizando escalas


para mostrar las cantidadesla interfaz debe ser como en la figura siguiente, el programa presenta dos
escalas verticales y una barra de menú que abre varias opciones.

La escala izquierda deberá de representar la temperatura en grados Fahrenheit y la escala de derecha


deberá mostrar la temperatura equivalente en grados centígrados. La primera opción de la barra del menú,
Deberá de abrir un menú de opciones que permita realizar la conversión en un sentido o en otro. La segunda
opción de la barra del menú hara que el Look&Feel de la aplicación sea el que se seleccione en el grupo de
botones que se depliega. Por ejemplo, la imagen siguiente muestra otro Look&Feel de la misma aplicación.

Cuando se desplace la posición del marcador de la escala con el ratón, la otra escala se debe de actualizar
inmediatamente para reflejar la misma temperatura en la otra unidad de medida.

Programacion Java Página 71 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Módulo 8. Paquete [Link]

Objetivo

Mostrar como utilizar los objetos contenidos dentro del paquete [Link] para el manejo de archivos y
obtención de datos a través del buffer

Introducción

Todo dato tiene un origen de entrada o un destino de salida (convenientemente en inglés: I/O). Un
programa trabaja con datos que provienen de una entrada la cual puede ser un teclado, un archivo en disco
o un socket a través de la red. Así mismo un programa genera resultados enviándolos a una salida la cual
puede ser la pantalla, un archivo en disco o un socket a través de la red. Como podemos comprender hay
distintos orígenes de entrada y destinos de salida para los datos, en Java todos estos se consideran flujos (en
inglés: streams) de datos para los cuales disponemos, en la API estándar, del paquete [Link] especializado
en la tarea de poder controlar estos flujos con cierta abstracción sobre el origen de los mismos, gracias a
esto siempre podemos recurrir al mismo grupo de clases independientemente del caso a tratar.

Flujos de entrada y salida

Así que en Java podemos tener un flujo de entrada (en ingles: input stream) por el cual recibimos datos
desde el exterior de nuestro programa, o un flujo de salida (en ingles: output stream) el cual envía nuestros
datos hacia un cierto destino.

Existen dos tipos de flujos según el tipo de dato:

 Flujos binarios – byte (8-bit): Es el tipo de flujo mas primitivo y portable, de echo cualquier otro
tipo de flujo esta construido sobre este porque hablando a bajo nivel todas las operaciones de I/O
son flujos de bytes. Nos permitirá trabajar adecuadamente con datos binarios tales como archivos
de imagen, sonido, etc. Las clases principales para manejar estos flujos son las clases abstractas
InputStream y OutputStream de las cuales heredan otras sub-clases que implementan en formas
mas concretas la misma tarea.

 Flujos de caracteres – char (16-bit): Es un tipo de flujo de caracteres en codificación Unicode, listo
para la internacionalización, ideal para trabajar con texto plano. Las clases principales para manejar
estos flujos son las clases abstractas Reader y Writer de las cuales heredan otras sub-clases que
implementan en formas mas concretas la misma tarea. Cualquiera de estas clases realiza la
conversión correspondiente de byte a char para leer o de char a byte para escribir.

Esquema con las clases principales del paquete [Link]: InputStream, OutputStream, Reader, Writer, y sus
sub-clases directas:

Programacion Java Página 72 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Lectura y Escritura

En el proceso de lectura o escritura de datos tenemos siempre tres pasos:

 Abrir un flujo de datos, eligiendo el mas adecuado a la ocasión

 Leer o escribir datos mientras todavía queden

 Cerrar el flujo de datos, liberando el recurso.

Veamos algunos de los métodos principales para leer o escribir datos:

Lectura
La clase InputStream:

 int read() - Lee el próximo byte del flujo representado en un entero. Devuelve -1 si no quedan mas
datos que leer.

 int read(byte[] b) - Lee un arreglo de bytes del flujo.

Programacion Java Página 73 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

 int read(byte[] b, int off, int len) – Lee un arreglo de bytes del flujo, desde y hasta la posición
indicada.

La clase Reader:

 int read() – Lee el próximo carácter del flujo representado en un entero. Devuelve -1 si no quedan
mas datos que leer.

 int read(char[] cbuf) – Lee un arreglo de caracteres del flujo.

 int read(char[] cbuf, int off, int len) – Lee un arreglo de caracteres del flujo, desde y hasta la
posición indicada.

Escritura
La clase OutputStream:

 void write(int b) – Escribe un solo byte en el flujo.

 void write(byte[] b) – Escribe un arreglo de bytes en el flujo.

 void write(byte[] b, int off, int len) – Escribe una porción de un arreglo de bytes en el flujo.

La clase Writer:

 void write(int c) – Escribe un solo carácter en el flujo.

 void write(char[] cbuf) – Escribe un arreglo de caracteres en el flujo.

 void write(char[] cbuf, int off, int len) - Escribe una porción de un arreglo de caracteres en el flujo.

Entrada y Salida estándar

La clase System, en el paquete [Link] de la API estándar, posee referencias estáticas hacia tres objetos
que representan flujos de datos ya abiertos y preparados para poder usarse. Estos flujos son:

 InputStream in (InputStream) – Flujo de entrada estándar. Típicamente corresponde al teclado.

 PrintStream out (OutputStream) – Flujo de salida estándar. Típicamente corresponde a la pantalla.

 PrintStream err (OutputStream) – Flujo de salida estándar de errores. Típicamente corresponde a


la pantalla.

Cualquiera de estos flujos pueden ser redirigidos hacia otras fuentes o destinos.

[Link]

Es un tipo de excepción generalizada que es lanzada cuando algún tipo de operación I/O ah fallado. Esta
excepción debe de ser tratada ya sea manejándola con un bloque de código try-catch en el mismo momento
que se realice la operación o dejando que se propague hacia arriba en la pila de llamadas utilizando throws
IOException.

Programacion Java Página 74 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Manejo de Archivos

Archivo: “Dispositivo lógico para el almacenamiento permanente de información (PERSISTENCIA) en


dispositivos de memoria auxiliar: disco duro, disquetes, memorias USB, CD´s, DVD, etc.).

Clases de archivos
 Los archivos también se distinguen por:
 Por su contenido:
- Archivos tipo texto.
- Archivos binarios.
 Por su modo de acceso:
- Archivos secuenciales.
- Archivos Random.

Clase File:
File: Representa un archivo y las operaciones que se pueden hacer con él. No incluye las operaciones de
lectura y escritura en archivo.

Constructores

File f1 = new File (String fileName);


Crea una instancia File para el archivo fileName”.
File f2 = new File (“data1”);
File f3 = new File (“/~/~/~/fileX”);
File f4 = new File (arg[0]);
File f = new File (File pathDir, String fileName);
File f = new File (“/home/mario/JavaDir”);
File f = new File (dir, “[Link]”);

Métodos

public boolean canRead()


public boolean canWrite()
public boolean delete()
public boolean exists()
public String getAbsolutePath()
public String getName()
public boolean isDirectory()
public boolean isFile()
public long length()
public String[ list()

Ejemplo con File

Programacion Java Página 75 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

import [Link].*;

public class FilePrueba


{
public static void main(String ar[])
{
if( [Link] == 0)
{
[Link]("Falta el nombre del archivo a investigar ....");
[Link](2);
}
File f = new File( ar[0]);
[Link]("Nombre del archivo: " + [Link]());
if( [Link]())
{
[Link]("El Archivo " + ar[0] + " EXISTE ....");
}
else
{
[Link]("El Archivo " + ar[0] + " NO EXISTE ....");
[Link](3);
}
if ( [Link]())
{
[Link]("El Archivo " + ar[0] + " es un archivo ordinario ...");
}
else
{
[Link]("El Archivo " + ar[0] + " NO ES UN ARCHIVO ORDINARIO.");
// [Link](4);
}
if( [Link]())
{
String arreglo[] = [Link]();
for( int i = 0; i < [Link]; i++)
[Link](arreglo[i]);
[Link](5);
}
else
{
[Link]("El Archivo " + ar[0] + " NO ES UN DIRECTORIO..");
}
if( [Link]())
{
[Link]("El Archivo " + ar[0] + " tiene permiso de lectura...");
}
else
{
[Link]("El Archivo " + ar[0] + " NO tiene permiso de lectura...");
}
if( [Link]())
{
[Link]("El Archivo " + ar[0] + " tiene permiso de escritura...");

Programacion Java Página 76 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

}
else
{
[Link]("El Archivo " + ar[0] + " NO tiene permiso de escritura...");
}
//[Link]();
[Link]("Ruta Absoluta: " + [Link]());
}
}

Flujos (Streams)

Flujo: Un flujo representa un objeto que se puede utilizar para realizar una entrada o una salida de datos,
representa un canal de información de donde se puede leer o escribir información.

Existen dos tipos de flujo en Java: unos que trabajan con bytes y otros que trabajan con caracteres.

FLUJOS CON BYTES FLUJOS CON CARACTERES

Entrada de InputStream Reader


Datos
ByteArrayInputStream BufferedReader

FileInputStream CharArrayReader

FilterInputStream FilterReader

ObjectInputStream InputStreamReader

PipedInputStream PipeReader

StringBufferInputStream StringReader

Salida de Datos OutpuStream Writer

ByteArrayOutputStream BufferedWriter

FileOutputStream CharArrayWriter

FilterOutputStream FilterWriter

ObjectOutputStream OutputStreamWriter

PipedOutputStream PipedWriter

Programacion Java Página 77 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

PrintWriter

StringWriter

Ejemplo con Flujo de Caracteres: FileWriter - FileReader

import [Link].*;
public class PruebaFlujoCaracteres{
public static void main(String ar[])
throws IOException
{
String nombreArchivo="[Link]";
FileWriter escribir;
try{
escribir = new FileWriter(nombreArchivo);
for(char c='a'; c<='z'; c++){
[Link](c);
}
[Link]();
}catch (IOException e){
[Link]("Imposible abrir el archivo para escribir");
}
FileReader leer;
int c;
try{
leer = new FileReader(nombreArchivo);
c= [Link]();
while (c != -1){
[Link]((char)c);
c= [Link]();
}
[Link]();
}catch(IOException e){
[Link]("Imposible abrir el archivo para leer");
}
}
}

Archivos de Acceso Aleatorio

Programacion Java Página 78 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Son archivos que permiten acceder a ellos de forma aleatoria indicando la posición en la que se quiere
operar.

Clase RandomAccessFile: clase para el acceso aleatorio a archivos. Permite utilizar los archivos en modo
lectura y escritura simultáneamente.

Ejemplo

import [Link].*;

public class ArchivosRandom {


public static void main(String ar[])
throws IOException{
char c;
boolean finArchivo = false;
RandomAccessFile archivo;

try{

archivo = new RandomAccessFile("[Link]", "rw");


[Link]("El tamaño del archivo es:"+[Link]());
do{
try{
c = (char) [Link]();
[Link]([Link]()-1);
[Link]([Link](c));
}catch(EOFException e){
[Link]();
finArchivo = true;
[Link]("Convertido a mayusculas");
}
}while(!finArchivo);
} catch(FileNotFoundException e){
[Link]("No se encontro el archivo");
}catch(IOException e){
[Link]("Problemas con el archivo");
}

}
}

Filtros

Son clases que representan flujos que se conectan a otros flujos que ya existen para, leyendo a través de los
mismos, transformar los datos proporcionando métodos de lectura o escritura más apropiados para un
programador.

Programacion Java Página 79 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Clases que trabajan con caracteres

Ejemplo con Filtros y flujo de caracteres

import [Link].*;
public class LeaArchivoTexto
{
public static void main(String ar[]) throws IOException
{
String entrada;
if( [Link] == 0)
{
[Link]("Falta el archivo a desplegar.....");
[Link](-1);
}

FileReader fr = new FileReader(ar[0]);


BufferedReader br = new BufferedReader( fr);

while( (entrada = [Link]()) != null)


{
[Link]( entrada);
}
[Link]();
[Link]();
}
}

Serializacion de objetos

Este mecanismo extiende las clases Java para I/O que vienen en su núcleo básico para que brinden soporte
para objetos.

Soporta la codificación de objetos como Stream de bytes y soporta la reconstrucción complementaria del
grado del objeto desde el Stream (decodificación).

Los objetos a ser almacenados y recuperados tienen que implementar las interfaces Serializable. Los
atributos no deben ser static.

Programacion Java Página 80 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Los objetos a ser almacenados y recuperados pueden referirse a otros objetos; estos objetos TIENEN QUE
SER almacenados y recuperados al mismo tiempo para mantener la relación entre los objetos: Cuando un
objeto es almacenado, TODOS los objetos que son invocados desde este objeto son almacenados también.

Como almacenar (grabar) objetos

Se requiere lo siguiente:

1. Instanciar un flujo de salida de bytes: FileOutputStream.

File f = new File (“archivo a crear”);

FileOutputStream fos = new FileOutputStream(f);

2. Se crea un ObjectOutputStream que grabe objetos (write) al FileOutputStream anterior.

ObjectOutputStream oos = new ObjectOutputStream (fos);

Se graba objetos serializados con el método:

public final void writeObject (Object o) throws IOException

//El objeto a ser grabado tiene que implementar la interface Serializable.

Después de grabar los objetos cerramos los archivos ObjectOutputStream y FileOutputStream así:

[Link]();

[Link]();

Como extraer (leer) objetos almacenados en forma “Serializada” en archivo.

1. Se instancia un flujo de entrada de bytes: InputStream.

File f = new File (“archivo de lectura”);


FileInputStream fis = new FileInputStream (f);
2. Creamos un ObjectInputStream para extraer (leer) los objetos del FileInputStream.

ObjectInputStream ois = new ObjectInputStream(fis);

3. Leemos ó extraemos los objetos serializados usando este método:

public final Object readObject() throws IOException, ClassNotFoundException

4. Como se extraen o se leen los objetos serializados en forma interactiva.

boolean masObjetos = true;


while(masObjetos){
try {
Object o = [Link]();
//Convertir al objeto real.
//Procesar la información del objeto real.
} catch (EOFException e){
masObjetos = false;
}

Programacion Java Página 81 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

5. Cerrar los archivos utilizados.

[Link];
[Link];

Ejemplo

import [Link].*;
import [Link].*;

public class ArchivoObjetos {


public static void main( String args[] )
{
try{
FileOutputStream archivo = new FileOutputStream("[Link]");
ObjectOutputStream salida = new ObjectOutputStream(archivo);
[Link]("Hoy es: ");
[Link](new Date());
[Link]();
}catch(IOException e){
[Link]("Problemas con el archivo");
}
try{
FileInputStream archivo2 = new FileInputStream("[Link]");
ObjectInputStream entrada = new ObjectInputStream(archivo2);
String hoy = (String)[Link]();
Date fecha = (Date)[Link]();
[Link]();
[Link](hoy + fecha);
}catch(IOException e){
[Link]("Problemas con el archivo");
}catch(Exception e){
[Link]("Error al leer un objeto");
}
}
}

Programacion Java Página 82 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Laboratorio Modulo 8. Usando la librería [Link]

Objetivo. Crear un programa que utilice los objetos de la librería [Link] según los requerimientos
pedidos

1. Crear un archivo que capture 2 números que capture el usuario y hacer una suma. El programa debe
de usar objeto Stream para la captura de los datos por parte del usuario

2. Crear un archivo de texto en C: que contenga la cadena ABCD y crear un programa en java que pueda
abrir y leer el contenido de dicho archivo. El contenido del archivo debe de ser desplegado en consola.

Programacion Java Página 83 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Módulo 9. Programación Multithreaded


Objetivo

Mostrar como crear una aplicación en java que maneje múltiples subprocesos y poderlos controlar y
comunicarse entre ellos

Introducción

Considerando el entorno multithread (multihilo), cada thread (hilo, flujo de control del programa)
representa un proceso individual ejecutándose en un sistema. A veces se les llama procesos ligeros o
contextos de ejecución. Típicamente, cada hilo controla un único aspecto dentro de un programa, como
puede ser supervisar la entrada en un determinado periférico o controlar toda la entrada/salida del disco.

Hilos
Todos los hilos comparten los mismos recursos, al contrario que los procesos, en donde cada uno tiene su
propia copia de código y datos (separados unos de otros). Gráficamente, los hilos (threads) se parecen en su
funcionamiento a lo que muestra la figura siguiente:

Hay que distinguir multihilo (multithread) de multiproceso. El multiproceso se refiere a dos programas que
se ejecutan "aparentemente" a la vez, bajo el control del Sistema Operativo. Los programas no necesitan
tener relación unos con otros, simplemente el hecho de que el usuario desee que se ejecuten a la vez.

Multihilo se refiere a que dos o más tareas se ejecutan "aparentemente" a la vez, dentro de un mismo
programa.

Se usa "aparentemente" en ambos casos, porque normalmente las plataformas tienen una sola CPU, con lo
cual, los procesos se ejecutan en realidad "concurrentemente", sino que comparten la CPU. En plataformas
con varias CPU, sí es posible que los procesos se ejecuten realmente a la vez.

Tanto en el multiproceso como en el multihilo (multitarea), el Sistema Operativo se encarga de que se


genere la ilusión de que todo se ejecuta a la vez. Sin embargo, la multitarea puede producir programas que
realicen más trabajo en la misma cantidad de tiempo que el multiproceso, debido a que la CPU está
compartida entre tareas de un mismo proceso. Además, como el multiproceso está implementado a nivel de
sistema operativo, el programador no puede intervenir en el planteamiento de su ejecución; mientras que

Programacion Java Página 84 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

en el caso del multihilo, como el programa debe ser diseñado expresamente para que pueda soportar esta
característica, es imprescindible que el autor tenga que planificar adecuadamente la ejecución de cada hilo,
o tarea.

Actualmente hay diferencias en la especificación del intérprete de Java, porque el intérprete de Windows
’95 conmuta los hilos de igual prioridad mediante un algoritmo circular (round-robin), mientras que el de
Solaris 2.X deja que un hilo ocupe la CPU indefinidamente, lo que implica la inanición de los demás.

Programas de flujo único


Un programa de flujo único o mono-hilvanado (single-thread) utiliza un único flujo de control (thread) para
controlar su ejecución. Muchos programas no necesitan la potencia o utilidad de múltiples flujos de control.
Sin necesidad de especificar explícitamente que se quiere un único flujo de control, muchos de los applets y
aplicaciones son de flujo único.

Por ejemplo, en la archiconocida aplicación estándar de saludo:

public class HolaMundo {

static public void main( String args[] ) {

[Link]( "Hola Mundo!" );

Aquí, cuando se llama a main(), la aplicación imprime el mensaje y termina. Esto ocurre dentro de un único
hilo de ejecución (thread).

Debido a que la mayor parte de los entornos operativos no solían ofrecer un soporte razonable para
múltiples hilos de control, los lenguajes de programación tradicionales, tales como C++, no incorporaron
mecanismos para describir de manera elegante situaciones de este tipo. La sincronización entre las múltiples
partes de un programa se llevaba a cabo mediante un bucle de suceso único. Estos entornos son de tipo
síncrono, gestionados por sucesos. Entornos tales como el de Macintosh de Apple, Windows de Microsoft y
X11/Motif fueron diseñados en torno al modelo de bucle de suceso.

Programas de flujo múltiple

En la aplicación de saludo, no se ve el hilo de ejecución que corre el programa. Sin embargo, Java posibilita
la creación y control de hilos de ejecución explícitamente. La utilización de hilos (threads) en Java, permite
una enorme flexibilidad a los programadores a la hora de plantearse el desarrollo de aplicaciones. La
simplicidad para crear, configurar y ejecutar hilos de ejecución, permite que se puedan implementar muy
poderosas y portables aplicaciones/applets que no se puede con otros lenguajes de tercera generación. En
un lenguaje orientado a Internet como es Java, esta herramienta es vital.

Si se ha utilizado un navegador con soporte Java, ya se habrá visto el uso de múltiples hilos en Java. Habrá
observado que dos applets se pueden ejecutar al mismo tiempo, o que puede desplazar la página del
navegador mientras el applet continúa ejecutándose. Esto no significa que el applet utilice múltiples hiloss,
sino que el navegador es multihilo, multihilvanado o multithreaded.

Programacion Java Página 85 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Los navegadores utilizan diferentes hilos ejecutándose en paralelo para realizar varias tareas,
"aparentemente" concurrentemente. Por ejemplo, en muchas páginas web, se puede desplazar la página e ir
leyendo el texto antes de que todas las imágenes estén presentes en la pantalla. En este caso, el navegador
está trayéndose las imágenes en un hilo de ejecución y soportando el desplazamiento de la página en otro
hilo diferente.

Las aplicaciones (y applets) multihilo utilizan muchos contextos de ejecución para cumplir su trabajo. Hacen
uso del hecho de que muchas tareas contienen subtareas distintas e independientes. Se puede utilizar un
hilo de ejecución para cada subtarea.

Mientras que los programas de flujo único pueden realizar su tarea ejecutando las subtareas
secuencialmente, un programa multihilo permite que cada thread comience y termine tan pronto como sea
posible. Este comportamiento presenta una mejor respuesta a la entrada en tiempo real.

Vamos a crear un programa llamado saludo creando tres hilos de ejecución individuales, que imprimen cada
uno de ellos su propio mensaje de saludo:

// Definimos unos sencillos hilos. Se detendrán un rato


// antes de imprimir sus nombres y retardos

class TestTh extends Thread {


private String nombre;
private int retardo;

// Constructor para almacenar nuestro nombre


// y el retardo
public TestTh( String s,int d ) {
nombre = s;
retardo = d;
}

// El metodo run() es similar al main(), pero para


// threads. Cuando run() termina el thread muere
public void run() {
// Retasamos la ejecución el tiempo especificado
try {
sleep( retardo );
} catch( InterruptedException e ) {
;
}

// Ahora imprimimos el nombre


[Link]( "Hola Mundo! "+nombre+" "+retardo );
}
}

public class MultiHola {


public static void main( String args[] ) {
TestTh t1,t2,t3;

// Creamos los threads


t1 = new TestTh( "Thread 1",(int)([Link]()*2000) );
t2 = new TestTh( "Thread 2",(int)([Link]()*2000) );

Programacion Java Página 86 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

t3 = new TestTh( "Thread 3",(int)([Link]()*2000) );

// Arrancamos los threads


[Link]();
[Link]();
[Link]();
}
}

Antes de entrar en más profundidades en los hilos de ejecución, se propone una referencia rápida de la
clase Thread.

La clase Thread
Es la clase que encapsula todo el control necesario sobre los hilos de ejecución (threads). Hay que distinguir
claramente un objeto Thread de un hilo de ejecución o thread. Esta distinción resulta complicada, aunque se
puede simplificar si se considera al objeto Thread como el panel de control de un hilo de ejecución (thread).
La clase Thread es la única forma de controlar el comportamiento de los hilos y para ello se sirve de los
métodos que se exponen en las secciones siguientes.

Métodos de Clase
Estos son los métodos estáticos que deben llamarse de manera directa en la clase Thread.

currentThread()

Este método devuelve el objeto thread que representa al hilo de ejecución que se está ejecutando
actualmente.

yield()

Este método hace que el intérprete cambie de contexto entre el hilo actual y el siguiente hilo ejecutable
disponible. Es una manera de asegurar que nos hilos de menor prioridad no sufran inanición.

sleep( long )

El método sleep() provoca que el intérprete ponga al hilo en curso a dormir durante el número de
milisegundos que se indiquen en el parámetro de invocación. Una vez transcurridos esos milisegundos,
dicho hilo volverá a estar disponible para su ejecución. Los relojes asociados a la mayor parte de los
intérpretes de Java no serán capaces de obtener precisiones mayores de 10 milisegundos, por mucho que se
permita indicar hasta nanosegundos en la llamada alternativa a este método.

Métodos de Instancia
Aquí no están recogidos todos los métodos de la clase Thread, sino solamente los más interesantes, porque
los demás corresponden a áreas en donde el estándar de Java no está completo, y puede que se queden
obsoletos en la próxima versión del JDK, por ello, si se desea completar la información que aquí se expone se
ha de recurrir a la documentación del interfaz de programación de aplicación (API) del JDK.

start()

Este método indica al intérprete de Java que cree un contexto del hilo del sistema y comience a ejecutarlo. A
continuación, el método run() de este hilo será invocado en el nuevo contexto del hilo. Hay que tener
precaución de no llamar al método start() más de una vez sobre un hilo determinado.

run()

Programacion Java Página 87 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

El método run() constituye el cuerpo de un hilo en ejecución. Este es el único método del interfaz Runnable.
Es llamado por el método start() después de que el hilo apropiado del sistema se haya inicializado. Siempre
que el método run() devuelva el control, el hilo actual se detendrá.

stop()

Este método provoca que el hilo se detenga de manera inmediata. A menudo constituye una manera brusca
de detener un hilo, especialmente si este método se ejecuta sobre el hilo en curso. En tal caso, la línea
inmediatamente posterior a la llamada al método stop() no llega a ejecutarse jamás, pues el contexto del
hilo muere antes de que stop() devuelva el control. Una forma más elegante de detener un hilo es utilizar
alguna variable que ocasione que el método run() termine de manera ordenada. En realidad, nunca se
debería recurrir al uso de este método.

suspend()

El método suspend() es distinto de stop(). suspend() toma el hilo y provoca que se detenga su ejecución sin
destruir el hilo de sistema subyacente, ni el estado del hilo anteriormente en ejecución. Si la ejecución de un
hilo se suspende, puede llamarse a resume() sobre el mismo hilo para lograr que vuelva a ejecutarse de
nuevo.

resume()

El método resume() se utiliza para revivir un hilo suspendido. No hay garantías de que el hilo comience a
ejecutarse inmediatamente, ya que puede haber un hilo de mayor prioridad en ejecución actualmente, pero
resume() ocasiona que el hilo vuelva a ser un candidato a ser ejecutado.

setPriority( int )

El método setPriority() asigna al hilo la prioridad indicada por el valor pasado como parámetro. Hay
bastantes constantes predefinidas para la prioridad, definidas en la clase Thread, tales como MIN_PRIORITY,
NORM_PRIORITY y MAX_PRIORITY, que toman los valores 1, 5 y 10, respectivamente. Como guía
aproximada de utilización, se puede establecer que la mayor parte de los procesos a nivel de usuario
deberían tomar una prioridad en torno a NORM_PRIORITY. Las tareas en segundo plano, como una
entrada/salida a red o el nuevo dibujo de la pantalla, deberían tener una prioridad cercana a MIN_PRIORITY.
Con las tareas a las que se fije la máxima prioridad, en torno a MAX_PRIORITY, hay que ser especialmente
cuidadosos, porque si no se hacen llamadas a sleep() o yield(), se puede provocar que el intérprete Java
quede totalmente fuera de control.

getPriority()

Este método devuelve la prioridad del hilo de ejecución en curso, que es un valor comprendido entre uno y
diez.

setName( String )

Este método permite identificar al hilo con un nombre menmónico. De esta manera se facilita la depuración
de programas multihilo. El nombre mnemónico aparecerá en todas las líneas de trazado que se muestran
cada vez que el intérprete Java imprime excepciones no capturadas.

getName()

Este método devuelve el valor actual, de tipo cadena, asignado como nombre al hilo en ejecución mediante
setName().

Creación de un Thread

Programacion Java Página 88 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Hay dos modos de conseguir hilos de ejecución (threads) en Java. Una es implementando el interfaz
Runnable, la otra es extender la clase Thread.

La implementación del interfaz Runnable es la forma habitual de crear hilos. Los interfaces proporcionan al
programador una forma de agrupar el trabajo de infraestructura de una clase. Se utilizan para diseñar los
requerimientos comunes al conjunto de clases a implementar. El interfaz define el trabajo y la clase, o
clases, que implementan el interfaz para realizar ese trabajo. Los diferentes grupos de clases que
implementen el interfaz tendrán que seguir las mismas reglas de funcionamiento.

Hay una cuantas diferencias entre interfaz y clase, que ya son conocidas y aquí solamente se resumen.
Primero, un interfaz solamente puede contener métodos abstractos y/o variables estáticas y finales
(constantes). Las clases, por otro lado, pueden implementar métodos y contener variables que no sean
constantes. Segundo, un interfaz no puede implementar cualquier método. Una clase que implemente un
interfaz debe implementar todos los métodos definidos en ese interfaz. Un interfaz tiene la posibilidad de
poder extenderse de otros interfaces y, al contrario que las clases, puede extenderse de múltiples
interfaces. Además, un interfaz no puede ser instanciado con el operador new; por ejemplo, la siguiente
sentencia no está permitida:

Runnable a = new Runnable(); // No se permite

El primer método de crear un hilo de ejecución es simplemente extender la clase Thread:

class MiThread extends Thread {

public void run() {

...

El ejemplo anterior crea una nueva clase MiThread que extiende la clase Thread y sobreescribe el método
[Link]() por su propia implementación. El método run() es donde se realizará todo el trabajo de la clase.
Extendiendo la clase Thread, se pueden heredar los métodos y variables de la clase padre. En este caso,
solamente se puede extender o derivar una vez de la clase padre. Esta limitación de Java puede ser superada
a través de la implementación de Runnable:

public class MiThread implements Runnable {

Thread t;

public void run() {

// Ejecución del thread una vez creado

En este caso necesitamos crear una instancia de Thread antes de que el sistema pueda ejecutar el proceso
como un hilo. Además, el método abstracto run() está definido en el interfaz Runnable y tiene que ser
implementado. La única diferencia entre los dos métodos es que este último es mucho más flexible. En el
ejemplo anterior, todavía está la oportunidad de extender la clase MiThread, si fuese necesario. La mayoría
de las clases creadas que necesiten ejecutarse como un hilo, implementarán el interfaz Runnable, ya que
probablemente extenderán alguna de su funcionalidad a otras clases.

Programacion Java Página 89 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

No pensar que el interfaz Runnable está haciendo alguna cosa cuando la tarea se está ejecutando.
Solamente contiene métodos abstractos, con lo cual es una clase para dar idea sobre el diseño de la clase
Thread. De hecho, si se observan los fuentes de Java, se puede comprobar que solamente contiene un
método abstracto:

package [Link];

public interface Runnable {

public abstract void run() ;

Y esto es todo lo que hay sobre el interfaz Runnable. Como se ve, un interfaz sólo proporciona un diseño
para las clases que vayan a ser implementadas. En el caso de Runnable, fuerza a la definición del método
run(), por lo tanto, la mayor parte del trabajo se hace en la clase Thread. Un vistazo un poco más profundo a
la definición de la clase Thread da idea de lo que realmente está pasando:

public class Thread implements Runnable {

...

public void run() {

if( tarea != null )

[Link]() ;

...

De este trocito de código se desprende que la clase Thread también implemente el interfaz Runnable.
[Link]() se asegura de que la clase con que trabaja (la clase que va a ejecutarse como un hilo) no sea nula
y ejecuta el método run() de esa clase. Cuando esto suceda, el método run() de la clase hará que corra como
un hilo.

A continuación se presenta un ejemplo, que implementa el interfaz Runnable para crear un programa
multihilo.

class java1001 {
static public void main( String args[] ) {
// Se instancian dos nuevos objetos Thread
Thread hiloA = new Thread( new MiHilo(),"hiloA" );
Thread hiloB = new Thread( new MiHilo(),"hiloB" );

// Se arrancan los dos hilos, para que comiencen su ejecución


[Link]();
[Link]();

// Aquí se retrasa la ejecución un segundo y se captura la


// posible excepción que genera el método, aunque no se hace

Programacion Java Página 90 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

// nada en el caso de que se produzca


try {
[Link]().sleep( 1000 );
}catch( InterruptedException e ){}

// Presenta información acerca del Thread o hilo principal


// del programa
[Link]( [Link]() );

// Se detiene la ejecución de los dos hilos


[Link]();
[Link]();
}
}
class NoHaceNada {

// Esta clase existe solamente para que sea heredada por la clase

// MiHilo, para evitar que esta clase sea capaz de heredar la clase

// Thread, y se pueda implementar el interfaz Runnable en su

// lugar

class MiHilo extends NoHaceNada implements Runnable {

public void run() {

// Presenta en pantalla información sobre este hilo en particular

[Link]( [Link]() );

Como se puede observar, el programa define una clase MiHilo que extiende a la clase NoHaceNada e
implementa el interfaz Runnable. Se redefine el método run() en la clase MiHilo para presentar información
sobre el hilo.

La única razón de extender la clase NoHaceNada es proporcionar un ejemplo de situación en que haya que
extender alguna otra clase, además de implementar el interfaz.

En el ejemplo muestra el mismo programa básicamente, pero en este caso extendiendo la clase Thread, en
lugar de implementar el interfaz Runnable para crear el programa multihilo.

class java1002 {
static public void main( String args[] ) {
// Se instancian dos nuevos objetos Thread
Thread hiloA = new Thread( new MiHilo(),"hiloA" );
Thread hiloB = new Thread( new MiHilo(),"hiloB" );

// Se arrancan los dos hilos, para que comiencen su ejecución

Programacion Java Página 91 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

[Link]();
[Link]();

// Aquí se retrasa la ejecución un segundo y se captura la


// posible excepción que genera el método, aunque no se hace
// nada en el caso de que se produzca
try {
[Link]().sleep( 1000 );
}catch( InterruptedException e ){}

// Presenta información acerca del Thread o hilo principal


// del programa
[Link]( [Link]() );

// Se detiene la ejecución de los dos hilos


[Link]();
[Link]();
}
}

class MiHilo extends Thread {


public void run() {
// Presenta en pantalla información sobre este hilo en particular
[Link]( [Link]() );
}
}

En ese caso, la nueva clase MiHilo extiende la clase Thread y no implementa el interfaz Runnable
directamente (la clase Thread implementa el interfaz Runnable, por lo que indirectamente MiHilo también
está implementando ese interfaz). El resto del programa es similar al anterior.

Y todavía se puede presentar un ejemplo más simple, utilizando un constructor de la clase Thread que no
necesita parámetros, tal como se presenta en el ejemplo siguiente. En los ejemplos anteriores, el
constructor utilizado para Thread necesitaba dos parámetros, el primero un objeto de cualquier clase que
implemente el interfaz Runnable y el segundo una cadena que indica el nombre del hilo (este nombre es
independiente del nombre de la variable que referencia al objeto Thread).

class java1003 {
static public void main( String args[] ) {
// Se instancian dos nuevos objetos Thread
Thread hiloA = new MiHilo();
Thread hiloB = new MiHilo();

// Se arrancan los dos hilos, para que comiencen su ejecución


[Link]();
[Link]();

// Aquí se retrasa la ejecución un segundo y se captura la


// posible excepción que genera el método, aunque no se hace
// nada en el caso de que se produzca
try {
[Link]().sleep( 1000 );

Programacion Java Página 92 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

}catch( InterruptedException e ){}

// Presenta información acerca del Thread o hilo principal


// del programa
[Link]( [Link]() );

// Se detiene la ejecución de los dos hilos


[Link]();
[Link]();
}
}

class MiHilo extends Thread {


public void run() {
// Presenta en pantalla información sobre este hilo en particular
[Link]( [Link]() );
}
}

Las sentencias en este ejemplo para instanciar objetos Thread, son mucho menos complejas, siendo el
programa, en esencia, el mismo de los ejemplos anteriores.

Arranque de un Thread

Las aplicaciones ejecutan main() tras arrancar. Esta es la razón de que main() sea el lugar natural para crear
y arrancar otros hilos. La línea de código:

t1 = new TestTh( "Thread 1",(int)([Link]()*2000) );

crea un nuevo hilo de ejecución. Los dos argumentos pasados representan el nombre del hilo y el tiempo
que se desea que espere antes de imprimir el mensaje.

Al tener control directo sobre los hilos, hay que arrancarlos explícitamente. En el ejemplo con:

[Link]();

start(), en realidad es un método oculto en el hilo de ejecución que llama a run().

Manipulación de un Thread
Si todo fue bien en la creación del hilo, t1 debería contener un thread válido, que controlaremos en el
método run().

Una vez dentro de run(), se pueden comenzar las sentencias de ejecución como en otros programas. run()
sirve como rutina main() para los hilos; cuando run() termina, también lo hace el hilo. Todo lo que se quiera
que haga el hilo de ejecución ha de estar dentro de run(), por eso cuando se dice que un método es
Runnable, es obligatorio escribir un método run().

En este ejemplo, se intenta inmediatamente esperar durante una cantidad de tiempo aleatoria (pasada a
través del constructor):

sleep( retardo );

Programacion Java Página 93 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

El método sleep() simplemente le dice al hilo de ejecución que duerma durante los milisegundos
especificados. Se debería utilizar sleep() cuando se pretenda retrasar la ejecución del hilo. sleep() no
consume recursos del sistema mientras el hilo duerme. De esta forma otros hilos pueden seguir
funcionando. Una vez hecho el retardo, se imprime el mensaje "Hola Mundo!" con el nombre del hilo y el
retardo.

Suspensión de un Thread

Puede resultar útil suspender la ejecución de un hilo sin marcar un límite de tiempo. Si, por ejemplo, está
construyendo un applet con un hilo de animación, seguramente se querrá permitir al usuario la opción de
detener la animación hasta que quiera continuar. No se trata de terminar la animación, sino desactivarla.
Para este tipo de control de los hilos de ejecución se puede utilizar el método suspend().

[Link]();

Este método no detiene la ejecución permanentemente. El hilo es suspendido indefinidamente y para volver
a activarlo de nuevo se necesita realizar una invocación al método resume():

[Link]();

Parada de un Thread
El último elemento de control que se necesita sobre los hilos de ejecución es el método stop(). Se utiliza
para terminar la ejecución de un hilo:

[Link]();

Esta llamada no destruye el hilo, sino que detiene su ejecución. La ejecución no se puede reanudar ya con
[Link](). Cuando se desasignen las variables que se usan en el hilo, el objeto Thread (creado con new)
quedará marcado para eliminarlo y el garbage collector se encargará de liberar la memoria que utilizaba.

En el ejemplo, no se necesita detener explícitamente el hilo de ejecución. Simplemente se le deja terminar.


Los programas más complejos necesitarán un control sobre cada uno de los hilos que lancen, el método
stop() puede utilizarse en esas situaciones.

Si se necesita, se puede comprobar si un hilo está vivo o no; considerando vivo un hilo que ha comenzado y
no ha sido detenido.

[Link]();

Este método devolverá true en caso de que el hilo t1 esté vivo, es decir, ya se haya llamado a su método
run() y no haya sido parado con un stop() ni haya terminado el método run() en su ejecución.

En el ejemplo no hay problemas de realizar una parada incondicional, al estar todos los hilos vivos. Pero si a
un hilo de ejecución, que puede no estar vivo, se le invoca su método stop(), se generará una excepción. En
este caso, en los que el estado del hilo no puede conocerse de antemano es donde se requiere el uso del
método isAlive().

Grupo de Hilos

Programacion Java Página 94 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Todo hilo de ejecución en Java debe formar parte de un grupo. La clase ThreadGroup define e implementa
la capacidad de un grupo de hilos.

Los grupos de hilos permiten que sea posible recoger varios hilos de ejecución en un solo objeto y
manipularlo como un grupo, en vez de individualmente. Por ejemplo, se pueden regenerar los hilos de un
grupo mediante una sola sentencia.

Cuando se crea un nuevo hilo, se coloca en un grupo, bien indicándolo explícitamente, o bien dejando que el
sistema lo coloque en el grupo por defecto. Una vez creado el hilo y asignado a un grupo, ya no se podrá
cambiar a otro grupo.

Si no se especifica un grupo en el constructor, el sistema coloca el hilo en el mismo grupo en que se


encuentre el hilo de ejecución que lo haya creado, y si no se especifica en grupo para ninguno de los hilos,
entonces todos serán miembros del grupo "main", que es creado por el sistema cuando arranca la aplicación
Java.

En la ejecución de los ejemplos de esta sección, se ha podido observar la circunstancia anterior. Por
ejemplo, el resultado en pantalla de uno de esos ejemplos es el que se reproduce a continuación:

% java java1002
Thread[hiloA,5,main]
Thread[hiloB,5,main]
Thread[main,5,main]
Como resultado de la ejecución de sentencias del tipo:

[Link]( [Link]() );

Para presentar la información sobre el hilo de ejecución. Se puede observar que aparece el nombre del hilo,
su prioridad y el nombre del grupo en que se encuentra englobado.

La clase Thread proporciona constructores en los que se puede especificar el grupo del hilo que se esta
creando en el mismo momento de instanciarlo, y también métodos como setThreadGroup(), que permiten
determinar el grupo en que se encuentra un hilo de ejecución.

Arrancar y Parar Threads

Ahora que ya se ha visto por encima como se arrancan, paran, manipulan y agrupan los hilos de ejecución, el
ejemplo un poco más gráfico,vamos a implementa un contador.

El progama arranca un contador en 0 y lo incrementa, presentando su salida tanto en la pantalla gráfica


como en la consola. Una primera ojeada al código puede dar la impresión de que el programa empezará a
contar y presentará cada número, pero no es así. Una revisión más profunda del flujo de ejecución del
applet, revelará su verdadera identidad.

En este caso, la clase java1004 está forzada a implementar Runnable sobre la clase Applet que extiende.
Como en todos los applets, el método init() es el primero que se ejecuta. En init(), la variable contador se
inicializa a cero y se crea una nueva instancia de la clase Thread. Pasándole this al constructor de Thread, el
nuevo hilo ya conocerá al objeto que va a correr. En este caso this es una referencia a java1004. Después de
que se haya creado el hilo, necesitamos arrancarlo. La llamada a start(), llamará a su vez al método run() de
la clase, es decir, a [Link](). La llamada a start() retornará con éxito y el hilo comenzará a ejecutarse
en ese instante. Observar que el método run() es un bucle infinito. Es infinito porque una vez que se sale de
él, la ejecución del hilo se detiene. En este método se incrementará la variable contador, se duerme 10
milisegundos y envía una petición de refresco del nuevo valor al applet.

Programacion Java Página 95 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Es muy importante dormirse en algún lugar del hilo, porque sino, el hilo consumirá todo el tiempo de la CPU
para su proceso y no permitirá que entren métodos de otros hilos a ejecutarse. Otra forma de detener la
ejecución del hilo sería hacer una llamada al método stop(). En el contador, el hilo se detiene cuando se
pulsa el ratón mientras el cursor se encuentre sobre el applet. Dependiendo de la velocidad del ordenador,
se presentarán los números consecutivos o no, porque el incremento de la variable contador es
independiente del refresco en pantalla. El applet no se refresca a cada petición que se le hace, sino que el
sistema operativo encolará las peticiones y las que sean sucesivas las convertirá en un único refresco. Así,
mientras los refrescos se van encolando, la variable contador se estará todavía incrementando, pero no se
visualiza en pantalla.

El uso y la conveniencia de utilización del método stop() es un poco dudoso y algo que quizá debería
evitarse, porque puede haber objetos que dependan de la ejecución de varios hilos, y si se detiene uno de
ellos, puede que el objeto en cuestión estuviese en un estado no demasiado consistente, y si se le mata el
hilo de control puede que definitivamente ese objeto se dañe. Una solución alternativa es el uso de una
variable de control que permita saber si el hilo se encuentra en ejecución o no, por ello, en el ejemplo se
utiliza la variable miThread que controla cuando el hilo está en ejecución o parado.

La clase anidada ProcesoRaton es la que se encarga de implementar un objeto receptor de los eventos de
ratón, para detectar cuando el usuario pulsa alguno de los botones sobre la zona de influencia del applet.

Suspender y Reanudar Threads


Una vez que se para un hilo de ejecución, ya no se puede rearrancar con el comando start(), debido a que
stop() concluirá la ejecución del hilo. Por ello, en ver de parar el hilo, lo que se puede hacer es dormirlo,
llamando al método sleep(). El hilo estará suspendido un cierto tiempo y luego reanudará su ejecución
cuando el límite fijado se alcance. Pero esto no es útil cuando se necesite que el hilo reanude su ejecución
ante la presencia de ciertos eventos. En estos casos, el método suspend() permite que cese la ejecución del
hilo y el método resume() permite que un método suspendido reanude su ejecución. En la versión
modificada del ejemplo anterior, haremos otro ejemplo y se modifica el applet para que utilice los métodos
suspend() y resume():

El uso de suspend() es crítico en ocasiones, sobre todo cuando el hilo que se va a suspender está utilizando
recursos del sistema, porque en el momento de la suspensión los va a bloquear, y esos recursos seguirán
bloqueados hasta que no se reanude la ejecución del hilo con resume(). Por ello, deben utilizarse métodos
alternativos a estos, por ejemplo, implementando el uso de variables de control que vigiles periódicamente
el estado en que se encuentra el hilo actual y obren el consecuencia.

public class java1005 extends Applet implements Runnable {

...

class ProcesoRaton extends MouseAdapter {


boolean suspendido;

public void mousePressed( MouseEvent evt ) {


if( suspendido )
[Link]();
else
[Link]();

suspendido = !suspendido;

Programacion Java Página 96 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

...

Para controlar el estado del applet, se ha modificado el funcionamiento del objeto Listener que recibe los
eventos del ratón, en donde se ha introducido la variable suspendido. Diferenciar los distintos estados de
ejecución del applet es importante porque algunos métodos pueden generar excepciones si se llaman desde
un estado erróneo. Por ejemplo, si el applet ha sido arrancado y se detiene con stop(), si se intenta ejecutar
el método start(), se generará una excepción IllegalThreadStateException.

Aquí podemos poner de nuevo en cuarentena la idoneidad del uso de estos métodos para el control del
estado del hilo de ejecución, tanto por lo comentado del posible bloqueo de recursos vitales del sistema,
como porque se puede generar un punto muerto en el sistema si el hilo de ejecución que va a intentar
revivir el hilo suspendido necesita del recurso bloqueado. Por ello, es más seguro el uso de una variable de
control como suspendido, de tal forma que sea ella quien controle el estado del hilo y utilizar el método
notify() para indicar cuando el hilo vuelve a la vida.

Estados de un Threat ( sincronización

Durante el ciclo de vida de un hilo, éste se puede encontrar en diferentes estados. La figura siguiente
muestra estos estados y los métodos que provocan el paso de un estado a otro. Este diagrama no es una
máquina de estados finita, pero es lo que más se aproxima al funcionamiento real de un hilo.

Nuevo Thread
La siguiente sentencia crea un nuevo hilo de ejecución pero no lo arranca, lo deja en el estado de Nuevo
Thread:

Thread MiThread = new MiClaseThread();

Thread MiThread = new Thread( new UnaClaseThread,"hiloA" );

Cuando un hilo está en este estado, es simplemente un objeto Thread vacío. El sistema no ha destinado
ningún recurso para él. Desde este estado solamente puede arrancarse llamando al método start(), o

Programacion Java Página 97 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

detenerse definitivamente, llamando al método stop(); la llamada a cualquier otro método carece de
sentido y lo único que provocará será la generación de una excepción de tipo IllegalThreadStateException.

Ejecutable
Ahora obsérvense las dos líneas de código que se presentan a continuación:

Thread MiThread = new MiClaseThread();

[Link]();

La llamada al método start() creará los recursos del sistema necesarios para que el hilo puede ejecutarse, lo
incorpora a la lista de procesos disponibles para ejecución del sistema y llama al método run() del hilo de
ejecución. En este momento se encuentra en el estado Ejecutable del diagrama. Y este estado es Ejecutable
y no En Ejecución, porque cuando el hilo está aquí no esta corriendo. Muchos ordenadores tienen solamente
un procesador lo que hace imposible que todos los hilos estén corriendo al mismo tiempo. Java implementa
un tipo de scheduling o lista de procesos, que permite que el procesador sea compartido entre todos los
procesos o hilos que se encuentran en la lista. Sin embargo, para el propósito que aquí se persigue, y en la
mayoría de los casos, se puede considerar que este estado es realmente un estado En Ejecución, porque la
impresión que produce ante el usuario es que todos los procesos se ejecutan al mismo tiempo.

Cuando el hilo se encuentra en este estado, todas las instrucciones de código que se encuentren dentro del
bloque declarado para el método run(), se ejecutarán secuencialmente.

Parado
El hilo de ejecución entra en estado Parado cuando alguien llama al método suspend(), cuando se llama al
método sleep(), cuando el hilo está bloqueado en un proceso de entrada/salida o cuando el hilo utiliza su
método wait() para esperar a que se cumpla una determinada condición. Cuando ocurra cualquiera de las
cuatro cosas anteriores, el hilo estará Parado.

Por ejemplo, en el trozo de código siguiente:

Thread MiThread = new MiClaseThread();

[Link]();

try {

[Link]( 10000 );

} catch( InterruptedException e ) {

la línea de código que llama al método sleep():

[Link]( 10000 );

hace que el hilo se duerma durante 10 segundos. Durante ese tiempo, incluso aunque el procesador
estuviese totalmente libre, MiThread no correría. Después de esos 10 segundos. MiThread volvería a estar
en estado Ejecutable y ahora sí que el procesador podría hacerle caso cuando se encuentre disponible.

Para cada una de los cuatro modos de entrada en estado Parado, hay una forma específica de volver a
estado Ejecutable. Cada forma de recuperar ese estado es exclusiva; por ejemplo, si el hilo ha sido puesto a

Programacion Java Página 98 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

dormir, una vez transcurridos los milisegundos que se especifiquen, él solo se despierta y vuelve a estar en
estado Ejecutable. Llamar al método resume() mientras esté el hilo durmiendo no serviría para nada.

Los métodos de recuperación del estado Ejecutable, en función de la forma de llegar al estado Parado del
hilo, son los siguientes:

 Si un hilo está dormido, pasado el lapso de tiempo

 Si un hilo de ejecución está suspendido, después de una llamada a su método resume()

 Si un hilo está bloqueado en una entrada/salida, una vez que el comando de entrada/salida
concluya su ejecución

 Si un hilo está esperando por una condición, cada vez que la variable que controla esa condición
varíe debe llamarse al método notify() o notifyAll()

Muerto
Un hilo de ejecución se puede morir de dos formas: por causas naturales o porque lo maten (con stop()). Un
hilo muere normalmente cuando concluye de forma habitual su método run(). Por ejemplo, en el siguiente
trozo de código, el bucle while es un bucle finito -realiza la iteración 20 veces y termina-:

public void run() {


int i=0;
while( i < 20 ) {
i++;
[Link]( "i = "+i );
}
}
Un hilo que contenga a este método run(), morirá naturalmente después de que se complete el bucle y run()
concluya.

También se puede matar en cualquier momento un hilo, invocando a su método stop(). En el trozo de código
siguiente:

Thread MiThread = new MiClaseThread();

[Link]();

try {

[Link]( 10000 );

} catch( InterruptedException e ) {

[Link]();

se crea y arranca el hilo MiThread, se duerme durante 10 segundos y en el momento de despertarse, la


llamada a su método stop(), lo mata.

Programacion Java Página 99 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

El método stop() envía un objeto ThreadDeath al hilo de ejecución que quiere detener. Así, cuando un hilo
es parado de este modo, muere asíncronamente. El hilo morirá en el momento en que reciba ese objeto
ThreadDeath.

Los applets utilizarán el método stop() para matar a todos sus hilos cuando el navegador con soporte Java en
el que se están ejecutando le indica al applet que se detengan, por ejemplo, cuando se minimiza la ventana
del navegador o cuando se cambia de página.

El método isAlive()

El interfaz de programación de la clase Thread incluye el método isAlive(), que devuelve true si el hilo ha
sido arrancado (con start()) y no ha sido detenido (con stop()). Por ello, si el método isAlive() devuelve false,
sabemos que estamos ante un Nuevo Thread o ante un thread Muerto. Si devuelve true, se sabe que el hilo
se encuentra en estado Ejecutable o Parado. No se puede diferenciar entre Nuevo Thread y Muerto, ni entre
un hilo Ejecutable o Parado.

Programacion Java Página 100 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Laboratorio Modulo 9. Uso de Hilos en Java

Objetivo. Crear un programa en Java que sea capaz de controlar por intervalos varios procesos

1. Crear un programa que controle 3 subprocesos, los cuales se ejecuten en diferentes intervalos y que
manden a imprimir su estatus a pantalla.

Programacion Java Página 101 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Modulo 10. JDBC


Objetivo

Mostrar como conectar una aplicación de Java a una base de datos y generar procesos en conjunto

Introducción
JDBC son las siglas en ingles de Java Database Connectivity. Es un conjunto de clases que nos permite
acceder a diversos gestores de bases de datos en forma transparente.

Para cuestiones practicas, en este modulo nos enfocaremos a como conectarnos con el motor de base de
datos MySQL.

Una vez instalada la base de datos (tema que es aparte de este curso), podremos ver podemos conectarnos
con ella y ejecutar los comandos SQL básicos: SELECT, INSERT, UPDATE y DELETE.

También, por si acaso, crearemos desde Java la tabla de base de datos que vamos a usar y la borraremos.

El driver con la base de datos


Lo primero que necesitamos para conectarnos con una base de datos es un Driver (o Connector) con ella.
Ese Driver es la clase que, de alguna forma, sabe cómo hablar con la base de datos. Desgraciadamente (y
hasta cierto punto es lógico), java no viene con todos los Drivers de todas las posibles bases de datos del
mercado. Debemos ir a internet y obtener el Driver, normalmente en la página de nuestra base de datos

Para el caso de MySQL, podemos descargarlo de

[Link]

Nos bajamos el [Link] (o bien la versión mas nueva disponible en el momento), lo


desempaquetamos en algún sitio y nos quedamos con el [Link] que viene
dentro. En ese jar está la clase Driver que nos interesa.

Tendremos que poner ese jar accesible en nuestro proyecto. Dependiendo de qué utilicemos para
programar en java hay muchas opciones.

 Guardarlo en la carpeta <DIRECTORIO_DE_JAVA>/jre/lib/ext. Si has hecho una instalación por


defecto en Windows, estará en C:\Archivos de Programa\Java\jdk1.5.0_05\jre\lib\ext. Esta es la
carpeta en la que java nos deja poner jar adicionales para que se encuentren por defecto. Es buena
idea ponerlo aquí si vamos a hacer muchos programas con base de datos. Si solo vamos a hacer
uno, es mejor no ponerlo aquí. Si decidimos usar esta carpeta, también debemos tener la
precaución de ir retirando jars de versiones antiguas cuando pongamos las nuevas, o tendremos
problemas.

 Ponerlo en la variable de entorno CLASSPATH, siempre que nuestro IDE (eclipse, netbeans, etc)
haga caso de esa variable. Si trabajas con una ventana de ms-dos (símbolo del sistema), puedes
poner esto

C:\> set CLASSPATH=<PATH_DEL_JAR>\[Link]

 Añadirlo en nuestro IDE. En el ejemplo de eclipse, damos con el botón derecho del ratón sobre el
proyecto, para sacar el menú y elegimos "properties"->"java build path"-

Programacion Java Página 102 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

 >"Libraries"->"Add external JARs..." y seleccionamos nuestro jar.

Conectarnos con la base de datos


Una vez que java tiene el jar accesible y sabe dónde encontrarlo, ya podemos empezar con el código. Lo
primero es conectarse con la base de datos

El código puede ser como este

import [Link];
import [Link];
...
try
{
[Link]("[Link]");
Connection conexion = [Link]("jdbc:mysql://localhost/agenda", "root",
"LA_PASSWORD");
...

En primer lugar hemos hecho los import adecuados para poder obtener la conexión.

Luego hay que asegurarse de que java carga el Driver. Para ello hay dos opciones. Hacer un new de él o bien
instanciarlo con [Link]("nombre de clase"), que es como hacer el new, pero de una forma rara.

La ventaja de hacerlo con [Link]() es que sólo necesitaremos el Driver de una base de datos si lo
usamos. Me explico. Imagina que haces un programa que permite permite conectarse con varias bases de
datos distintas: MySQL, PostGres, Oracle, etc. En algún sitio damos a elegir al usuario qué tipo de base de
datos tiene.

Si hacemos new de los Driver, tendremos que hacer unos if para en función de la elegida, hacer new de uno
o de otro. El problema es que en nuestro código estarán los import y los new de todos los Driver de todas las
bases de datos necesaras, los vayamos a usar o no. El programa no compilará y no correrá si no tiene todos
los Driver accesibles.

/* Todos estos import son necesarios para que compilen los news correspondientes */
import driver_de_mysql;
import driver_de_postgres;
import driver_de_oracle;
...
if (ha_elegido_mysql)
new driver_de_mysql();
if (ha_elegido_postgres)
new driver_de_postgres();
if (ha_elegido_oracle)
new driver_de_oracle();

Sin embargo, con [Link]() no necesitamos el import. Haremos los mismos if de antes, pero
usaremos simplemente String distintos para llamar a [Link](). No necesitamos los import y no
necesitamos los jar con los Driver, salvo el jar con el Driver que realmente elija el usuario. Es cosa suya tener
instalado SU driver de SU base de datos.

/* No hacen falta imports */


...
if (ha_elegido_mysql)

Programacion Java Página 103 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

[Link]("driver_de_mysql");
if (ha_elegido_postgres)
[Link]("driver_de_postgres");
if (ha_elegido_oracle)
[Link]("driver_de_oracle");

Una vez que nos hemos asegurado que java tiene el Driver cargado, simplemente pediremos conexión con la
base de datos a la clase DriverManager.

Connection conexion = [Link]("jdbc:mysql://localhost/agenda", "root",


"LA_PASSWORD");

DriverManager tiene muchos métodos getConnection() con parámetros variados. Todos son variantes de lo
mismo y la información que suministramos es la misma. Aquí hemos utilizado uno con tres parámetros
String, que vamos a explicar.

 url: Es una cadena que nos permite localizar la base de datos. Para mysql, el formato es
"jdbc:mysql://computadora_donde_corre_la_base_de_datos/nombre_base_datos". Donde se
pone el nombre o IP dla computadora en el que se encuentra nuestro servidor de base de datos y el
nombre de la base de datos. En nuestro ejemplo, tenemos el servidor de base de datos corriendo
en el mismo computadora que el programa java, por lo que ponemos localhost. La base de datos la
he llamado agenda. El comando SQL para crear la base de datos agenda sería

mysql> CREATE DATABASE agenda;

 user: Un usuario válido para la base de datos.

 password: La clave del usuario.

Si todo va bien, tendremos nuestra conexión a la base de datos. Si va mal, saltará una excepción. Por eso es
importante (y obligatorio para que compile) meter todo esto en un try-catch.

Creamos la tabla en Base de Datos ... y la borramos.

Para enviar comandos SQL a la base de datos, se usa la clase Statement de java. Esta clase se obtiene a
partir de la conexión, de esta forma:

Statement st = [Link]();

por supuesto, dentro de un try-catch.

Statement tiene muchos métodos, pero hay dos interesentantes: executeUpdate() y executeQuery(). El
primero se usa para sentencias SQL que impliquen modificaciones en la base de datos (INSERT, UPDATE,
DELETE, etc). El segundo sólo para consultas (SELECT y similares).

Nuestra creación de tabla afecta a la base de datos, así que con executeUpdate().

[Link]("CREATE TABLE contacto (id INT AUTO_INCREMENT, PRIMARY KEY(id), nombre


VARCHAR(20), apellidos VARCHAR(20), telefono VARCHAR(20))");

Esto crea una tabla contacto con cuatro campos: id, nombre, apellidos y telefono.

Para borrar la tablita esta, lo mismo, pero con DROP en vez de CREATE.

[Link]("DROP TABLE contacto");

Programacion Java Página 104 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Insertar datos en la base de datos


Vamos a hacer un esfuerzo de imaginación y supongamos que no hemos borrado la tabla contacto, que
sigue existiendo en base de datos. Vamos a meterle datos.

String nombres[]={"Juan","Pedro","Antonio"};
String apellidos[]={"Gomez","Lopez","Alvarez"};
String telefonos[]={"123","456","789"};
...
for (int i=0;i<[Link];i++)
[Link]("INSERT INTO contacto (nombre, apellidos, telefono) VALUES
('"+nombres[i]+"','"+apellidos[i]+"','"+telefonos[i]+"' )");

también en un try-catch.

Pondremos los datos a insertar en unos arrays. Tú puedes recogerlos de un sitio con más sentido. Por
ejemplo, si es una agenda de contactos, lo mejor es pedírselos al usuario. Por simplicidad y porque para el
ejemplo sea comprobable de forma mas facil, se colocaran en un array y con un bucle y se iran insertando.

La sentencia INSERT se va componiendo a base de sumar cadenas. Sería más eficiente con un StringBuffer,
pero así se simplifica algo el ejemplo.

Fíjate que en el INSERT metemos comillas simples para los valores de cadenas, es decir, en nombre, apellidos
y telefono. El INSERT sería, de verdad, así

INSERT INTO contacto (nombre, apellidos, telefono) VALUES ('Juan', 'Gomez', '123');

Ahí se ven más claras las comillas simples para los datos que definimos como VARCHAR en la creación de la
tabla, es decir, Juan, Gomez y 123. Por eso en el código las hemos puesto

...VALUES ('"+nombres[i]+"','"...

Si fuesen datos numéricos no harían falta, son cosas de SQL, pero tenemos que tener cuidado de
componerlas bien.

Consultar datos de la base de datos


Vamos a hacer ahora una consulta de los datos que acabamos de insertar en la base de datos. Las consultas
se hacen con executeQuery() y nos devolverán un ResultSet.

El ResultSet de alguna forma representa una conexión hacia los datos. En el ResultSet NO están todavía los
datos. Según se los vayamos pidiendo, los irá trayendo de base de datos. Esto quiere decir que si una
consulta devuelve muchos resultados, no se nos va a llenar la memoria por el hecho de hacer la consulta.

Para traer el primer resultado, debemos llamar el método next() del ResulSet. Para el siguiente otro next() y
así sucesivamente hasta que next() devuelva false, indicando que ya no quedaban datos. El código puede ser
así

ResultSet rs = [Link]("SELECT * FROM contacto");


while ([Link]())
{
[Link]("nombre="+[Link]("nombre")+
", apellidos="+[Link]("apellidos")+
", telefono="+[Link]("telefono"));
}

Programacion Java Página 105 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

[Link]();

Hemos hecho un SELECT para obtener los datos. Luego un bucle while([Link]()), es decir, mientras next()
vaya trayendo resultados.

Después de next(), el resultado recién traido está disponible en el ResulSet. La forma de recoger los campos
es pedirlos con algún método get(). Si sabemos de qué tipo es el dato, podemos pedirlo con getInt(),
getString(), etc. Si no lo sabemos o nos da igual (como en este caso), bastará con un getObject(), capaz de
traer cualquier tipo de dato.

En estos métodos get() podemos pasar como parámetro un entero, empezando en 1, que es el número del
campo en el SELECT. Es decir, si hacemos SELECT campo1, campo2, campo3 ..., si pedimos getObject(1)
obtenemos el valor de campo1, para getObject(2) el de campo2, etc.

Otra opción que a mi me gusta más, es pasar el nombre del campo, como se muestra en el código. Así, en el
ejemplo de antes, getObject("campo1") nos devuelve el valor del campo1.

Update en la base de datos

Para UPDATE usamos executeUpdate(). Vamos a cambiar el número de teléfono de Juan. Ya que en la tabla
hemos puesto un campo id, vamos primero a obtener el id de Juan para luego usarlo en el UPDATE. Esto no
tiene por qué ser así, es sólo el ejemplo.

Para obtener el id:

rs = [Link]("SELECT id FROM contacto WHERE nombre='Juan'");


[Link]();
int id = [Link]("id");

Es un SELECT para obtener el campo id de Juan. Con [Link]() hacemos que venga el primer resultado de la
consulta (y único en nuestro ejemplo). Como sabemos que es un INT, lo recogemos con getInt() y lo
guardamos.

Para hacerlo bien, deberíamos ver si [Link]() devuelve o no resultado (quizás no haya nadie que se llame
Juan en la base de datos) o si devuelve más de uno (más de un Juan en la base de datos), pero no vamos a
complicarnos la vida en este ejemplo sencillo.

Ahora, sabiendo el id, podemos hacer el UPDATE.

[Link]("UPDATE contacto SET telefono='111' WHERE id="+id);

Esta vez, como el campo id es numérico, no hemos puesto las comillas simples.

Borrar datos de la base de datos

El borrado se hace con DELETE y executeUpdate(). Vamos a borrar a Pedro, que nos hemos peleado con él.
Obtenemos primero su id, igual que antes.

rs = [Link]("SELECT id FROM contacto WHERE nombre='Pedro'");


[Link]();
id = [Link]("id");

Programacion Java Página 106 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

y ahora lo borramos

[Link]("DELETE FROM contacto WHERE id="+id);

Cerrar conexiones

Los Connection, Statement y ResultSet con conexiones abiertas con base de datos. Debemos cerrarlas.

ResultSet se cierra solo cuando hacemos otra llamada execute() al Statement del que obtuvimos este
ResultSet o bien cuando el recolector de basura "recolecta" al ResultSet. No nos preocupa en principio que
se quede abierto, porque se acabará cerrando solo.

Eso sí, no podemos hacer nada con el Statement hasta que hayamos terminado con el ResultSet o se nos
cerrará. Si necesitamos realizar otra cosa con base de datos, debemos crear otro Statement distinto.

Cuando terminemos con el Statement, lo cerramos con [Link]().

Cuando terminemos con la Connection, la cerramos con [Link]().

Programacion Java Página 107 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Laboratorio Modulo 10. JDBC

Objetivo. Conectar una aplicación de Java a una base de Datos de MySQL y generar operaciones con ella.

1. Crear una aplicación de Java para probar una conexión a una base de datos de [Link] base de datos
llamada prueba y que tiene una tabla llamada persona. Dicha tabla tiene 3 campos. Id, nombre,
nacimiento.

 La aplicación deberá de crear la tabla e insertarle datos.


 La aplicación deberá de desplegar todos los registros deque contenga la tabla anterior
 La aplicación deberá de Actualizar los datos existentes.
 La aplicación deberá de Mostrar las actualizaciones.
 La aplicación deberá de borrar los datos

Programacion Java Página 108 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Conclusion

Java tiene importantes ventajas, no sólo como un lenguaje comercial, sino también como lenguaje de
enseñanza. Permite a los estudiantes a aprender programación orientada a objetos sin exponerlos a la
complejidad de C + +. Proporciona una base robusta de control de error en tiempo de compilación algo que
normalmente carecen lenguajes de programación. Permite introducir al alumno en la programación GUI,
redes, hilos, y otros conceptos importantes que se utilizan en el software de hoy en día.

Java se ha transformado en uno de los lenguajes de programación más utilizados de los departamentos de
informática y sus aplicaciones parecen ser casi infinitas.

Programacion Java Página 109 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

APENDICE
RESOLUCION DE LABORATORIOS

Programacion Java Página 110 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Respuesta Laboratorio Modulo 2. Estructuras de Flujo y Control de Datos

Ejercicio 1

import [Link];

public class EstructuraRepetitivaWhile5 {


public static void main(String[] ar) {
Scanner teclado=new Scanner([Link]);
int x,nota,conta1,conta2;
x=1;
conta1=0;
conta2=0;
while (x<=10) {
[Link]("Ingrese nota:");
nota=[Link]();
if (nota>=7) {
conta1=conta1 + 1;
}else {
conta2=conta2 + 1;
}
x=x + 1;
}
[Link]("Cantidad de alumnos con notas mayores o iguales a 7:");
[Link](conta1);
[Link]("Cantidad de alumons con notas menores a 7:");
[Link](conta2);
}
}

Ejercicio2

import [Link];

public class EstructuraRepetitivaWhile10 {


public static void main(String[] ar) {
Scanner teclado=new Scanner([Link]);
int valor,x,suma1,suma2;
x=1;
suma1=0;
suma2=0;
[Link]("Primer lista");
while (x<=15) {
[Link]("Ingrese valor:");
valor=[Link]();

Programacion Java Página 111 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

suma1=suma1 + valor;
x=x + 1;
}
[Link]("Segunda lista");
x=1;
while (x<=15) {
[Link]("Ingrese valor:");
valor=[Link]();
suma2=suma2 + valor;
x=x + 1;
}
if (suma1>suma2) {
[Link]("Lista 1 mayor.");
} else {
if (suma2>suma1) {
[Link]("Lista2 mayor.");
} else {
[Link]("Listas iguales.");
}
}
}
}

Programacion Java Página 112 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Respuesta Laboratorio Modulo 4. Clases y Métodos

import [Link];
public class Empleado {
private Scanner teclado;
String nombre;
float sueldo;

public void inicializar() {


teclado=new Scanner([Link]);
[Link]("Ingrese el nombre del empleado:");
nombre=[Link]();
[Link]("Ingrese su sueldo:");
sueldo=[Link]();
}

public void pagaImpuestos() {


if (sueldo>3000) {
[Link]("Debe abonar impuestos");
} else {
[Link]("No paga impuestos");
}
}

public static void main(String[] ar) {


Empleado empleado1;
empleado1=new Empleado();
[Link]();
[Link]();
}
}

import [Link];
public class Operaciones {
private Scanner teclado;
int valor1,valor2;

public void inicializar() {


teclado=new Scanner([Link]);
[Link]("Ingrese primer valor:");
valor1=[Link]();
[Link]("Ingrese segundo valor:");
valor2=[Link]();
}

public void sumar() {


int suma;
suma=valor1+valor2;

Programacion Java Página 113 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

[Link]("La suma es:"+suma);


}

public void restar() {


int resta;
resta=valor1-valor2;
[Link]("La resta es:"+resta);
}

public void multiplicar() {


int multiplicacion;
multiplicacion=valor1*valor2;
[Link]("La multiplicación es:"+multiplicacion);
}

public void dividir() {


int division;
division=valor1/valor2;
[Link]("La división es:"+division);
}

public static void main(String[] ar) {


Operaciones opera;
opera=new Operaciones();
[Link]();
[Link]();
[Link]();
[Link]();
[Link]();
}
}

Programacion Java Página 114 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Respuesta Laboratorio Modulo 5. Gestión de Excepciones

Ejercicio 1

public class ExcepcionEnArray {


int[] array = {0, 1, 2, 3, 4, 5};
int getValor(int indice) {
return array[indice];
}
public static void main(String[] args) {
ExcepcionEnArray ea = new ExcepcionEnArray();
try {
[Link](6);
} catch (ArrayIndexOutOfBoundsException e) {
[Link]("Excepción: indice de array fuera de limites" + [Link]());
}
}
}

Ejercicio 2

class MiExcepcion extends Exception {


String mensaje;
public MiExcepcion(String mensaje) {
[Link] = mensaje;
}
public String getMensaje() {
return mensaje;
}
}

public class PropiaClaseExcepcion {


public static void main(String[] args) {
try {
throw new MiExcepcion("mi propia Excepción");
} catch(MiExcepcion e) {
[Link]("excepción: " + [Link]());
}
}
}

Programacion Java Página 115 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Respuesta Laboratorio Modulo 7. GUI de Java

import [Link].*;
import [Link].*;
import [Link].*;
import [Link].*;
import [Link].* ;

// La clase se base en un JFrame e implementa los interfaces que se


// indicant

public class java1427 extends JFrame implements ActionListener,


SwingConstants, ChangeListener {
// Modos de funcionamiento, o de conversión
private static final int MODO_F2C = 1;
private static final int MODO_C2F = 2;

// Valores máximos y mínimos de las barras de desplazamiento


private static final int FMIN = 0;
private static final int FMAX = 140;
private static final int CMIN = -20;
private static final int CMAX = 60;

private static final Dimension vpad10 = new Dimension( 1,10 );

// Modo inicial
int modo = MODO_F2C;

static java1427 MiFrame;


private Container cliente;
private JSlider fahrenheit;
private JSlider centigrade;
private JLabel valorF;
private JLabel valorC;
private JMenuBar barraMenu;
private JMenu menuModo;
private JCheckBoxMenuItem opcionF2C;
private JCheckBoxMenuItem opcionC2F;
private JMenu menuLaf;
private ButtonGroup grupoLaf;
private JRadioButtonMenuItem opcionLaf;
private [Link] laf[];

// Este es el contrsuctor de la clase, que crea la barra del


// menú superior, las barras de desplazamiento que van a ir
// mostrando las conversiones de temperatura y registra los
// receptores de eventos
public java1427() {
super( "Ejercicio de Java, Swing" );

// Los dos paneles correspondientes a cada sistema de grados

Programacion Java Página 116 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

JPanel panelFH;
JPanel panelCG;

barraMenu = new JMenuBar();


menuModo = new JMenu( "Modo" );
menuLaf = new JMenu( "LookAndFeel" );
grupoLaf = new ButtonGroup();

// Se crean las opciones correspondientes a los modos de conversión


// se añaden a la barra superior
opcionF2C = new JCheckBoxMenuItem(
"Conversion Fahrenheit a Centigrados",true );
opcionC2F = new JCheckBoxMenuItem(
"Conversion Centigrados a Fahrenheit",false );
[Link]( this );
[Link]( this );
[Link]( opcionF2C );
[Link]( opcionC2F );
[Link]( menuModo );
// Se crean las opciones correspondientes a los look&feels
// disponibles se añaden a la barra superior
[Link] laf[] =
[Link]();
for( int i=0; i < [Link]; i++ ) {
opcionLaf = new JRadioButtonMenuItem( laf[i].getName() );
[Link]( this );
if( i == 0 )
[Link]( true );
[Link]( opcionLaf );
[Link]( opcionLaf );
}
[Link]( menuLaf );
// Se añade la barra de menú al Frame
[Link]( barraMenu );
// Se habilitan los eventos
enableEvents( AWTEvent.WINDOW_EVENT_MASK );
[Link]( laf[0] );

// El área cliente del frame, correspondiente a la parte


// que queda por debajo de la barra de menú, se divide en
// dos columnas
cliente = [Link]();
//[Link]( new BoxLayout( cliente,BoxLayout.X_AXIS ) );
[Link]( new GridLayout( 1,2 ) );

// Se crea el panel sobre el que se va a colocar la barra


// correspondiente a los grados Fahrenheit, situando en la parte
// inferior una etiqueta con el valor numérico correspondiente
// a la conversión o al valor convertido
panelFH = new JPanel();
[Link]( new TitledBorder( "Fahrenheit" ) );
[Link]( new BoxLayout( panelFH, BoxLayout.Y_AXIS ) );

Programacion Java Página 117 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

fahrenheit = new JSlider( VERTICAL,FMIN,FMAX,0 );


[Link]( 20 );
[Link]( 5 );
[Link]( true );
[Link]( true );
[Link]( this );

[Link]( fahrenheit );
[Link]( [Link]( vpad10 ) );
valorF = new JLabel( "00000",CENTER );
[Link]( valorF );

// Se crea el panel sobre el que se va a colocar la barra


// correspondiente a los grados Centígrados, situando en la parte
// inferior una etiqueta con el valor numérico correspondiente
// a la conversión o al valor convertido
panelCG = new JPanel() ;
[Link]( new TitledBorder( "Centigrados" ) );
[Link]( new BoxLayout( panelCG, BoxLayout.Y_AXIS ) );

centigrade = new JSlider( VERTICAL,CMIN,CMAX,0 );


[Link]( 20 );
[Link]( 5 );
[Link]( true );
[Link]( true );
[Link]( this );
[Link]( false );

[Link]( centigrade );
[Link]( [Link]( vpad10 ) );
valorC = new JLabel( "00000",CENTER );
[Link]( valorC );

// Se incorporan los paneles al frame


[Link]( panelFH );
[Link]( panelCG );

// Se fuerzan las barras de desplazamiento a que se


// inicialicen a valores predefinidos
//[Link]( FMAX ) ;
}

// Control del cambio de valor en las barras de


// desplazamiento. Se detecta el cambio en una y, por
// simpatía se muestra el valor convertido en la otra
public void stateChanged( ChangeEvent ce ) {
JSlider js = (JSlider)[Link]();

int valor = [Link]();

//[Link]( "Cambio estado -> "+valor );

if( [Link](fahrenheit) && modo == MODO_F2C ) {

Programacion Java Página 118 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

[Link]( [Link](valor) );
actcualizaBarraCG( valor );
}
else if( [Link](centigrade) && modo == MODO_C2F ) {
[Link]( [Link](valor) );
actualizaBarraFH( valor );
}
}

// Actualiza la barra que muestra la temperatura en


// grados Fahrenheit
private void actualizaBarraFH( int c ) {
int f;

f = (int)( (c * 9) / 5 + 32 + 0.5 );
[Link]( [Link](f) );
[Link]( f );
}

// Actualiza la barra que muestra la temperatura en


// grados Centígrados
private void actcualizaBarraCG( int f ) {
int c;

c = (int)( (f-32) * 5 / 9 + 0.5 );


[Link]( [Link]( c ) );
[Link]( c );
}

// Proceso de los eventos de alto nivel. En realidad está


// controlándose solamente cuando el usuario cierra la
// ventana, para concluir ejecución la aplicación, el resto
// se pasan hacia arriba en el árbol jerárquico
public void processEvent( AWTEvent evt ) {
if( [Link]() == WindowEvent.WINDOW_CLOSING ) {
[Link]( 0 );
}
else {
[Link]( evt );
}
}

// Este método es el que controla la acción por la cual


// se ha demostrado interés, que en este caso concreto es
// la opción que se selecciona entre las dos que presenta
// la barra de menú y que permite que la conversión de
// temperaturas sea en una dirección u otra
// Y también el caso en que se quiera cambiar de apariencia
// la ventana, para tener un look-and-feel diferente al que
// se instala por defecto
public void actionPerformed( ActionEvent evt ) {

Programacion Java Página 119 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

// Aqui controlamos el cambio de conversión


if( [Link]() instanceof JCheckBoxMenuItem ) {
JCheckBoxMenuItem jc = (JCheckBoxMenuItem)[Link]();

if( [Link]( opcionF2C ) ) {


[Link]( false );
[Link] = MODO_F2C;
[Link]( true );
[Link]( false );
}
else {
[Link]( false );
[Link] = MODO_C2F;
[Link]( true );
[Link]( false );
}
}
// Y aqui el cambio de apariencia de la ventana en general
if( [Link]() instanceof JRadioButtonMenuItem ) {
JRadioButtonMenuItem rb = (JRadioButtonMenuItem)[Link]();
Component root = [Link]( MiFrame );
// Aquí se cambia la forma del cursor, para que aparezca el cursor
// de espera predefinido por la plataforma sobre la que se está
// ejecutando el programa
[Link]( [Link]( Cursor.WAIT_CURSOR ) );
try {
if( [Link]() && [Link]().equals("Windows") ) {
[Link](
"[Link]" );
[Link](
[Link]( MiFrame ) );
} else if( [Link]() && [Link]().equals("CDE/Motif") ) {
[Link](
"[Link]" );
[Link](
[Link]( MiFrame ) );
} else if( [Link]() && [Link]().equals("Metal") ) {
[Link](
"[Link]" );
[Link](
[Link]( MiFrame ) );
}
} catch( UnsupportedLookAndFeelException e ) {
// Si no está soportado el Look&Feel que se acaba de seleccionar,
// se presenta un mensaje al uso, se deshabilita el botón
// correspondiente ala opción del menú
// Una mejora sería poner el Look por defecto de la plataforma.
// Teniendo cuidado de volver a capturar las excepciones
[Link]( "No esta soportado el LookAndFeel: "+
[Link]() );
[Link]( false );
} catch( Exception e ) {
[Link]( "No puedo cargar el LookAndFeel: "+

Programacion Java Página 120 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

[Link]() );
}
// Finalmente, se recupera el cursor por defecto del sistema
[Link]( [Link]( Cursor.DEFAULT_CURSOR ) );
}
}

static public void main( String args[] ) {


MiFrame = new java1427();
[Link]( 300,300 );
[Link]( [Link] );
[Link]();
}
}

Programacion Java Página 121 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Respuestas Laboratorio 8. Uso de la librería [Link]

Ejercicio 1

import [Link].*;

public class SumaDatosTeclado{


public static void main(String args[])throws IOException{

//Creación del flujo para leer datos


InputStreamReader isr=new InputStreamReader([Link]);

//Creación del filtro para optimizar la lectura de datos


BufferedReader br=new BufferedReader(isr);
[Link]("Teclea el primer numero: ");

//Lectura de datos mediante el método readLine()


String texto1=[Link]();

//Conversión a int de la String anterior para poder sumar


int num1=[Link](texto1);

[Link]("Teclea el segundo numero: ");


String texto2=[Link]();
int num2=[Link](texto2);

//Sumar los dos enteros


[Link]("Suma de "+num1+" y "+num2+" es "+(num1+num2));
}
}

Ejercicio 2
 Se debe de crear previamente un archivo de texto en C: con el contenido “ABCDE”

import [Link];
import [Link];
import [Link];
import [Link];

public class BufferedReaderDemo {


public static void main(String[] args) throws Exception {

InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;

try{

Programacion Java Página 122 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

// open input stream [Link] for reading purpose.


is = new FileInputStream("c:/[Link]");

// create new input stream reader


isr = new InputStreamReader(is);

// create new buffered reader


br = new BufferedReader(isr);

int value=0;

// reads to the end of the stream


while((value = [Link]()) != -1)
{
// converts int to character
char c = (char)value;

// prints character
[Link](c);
}
}catch(Exception e){
[Link]();
}finally{

// releases resources associated with the streams


if(is!=null)
[Link]();
if(isr!=null)
[Link]();
if(br!=null)
[Link]();
}
}
}

Programacion Java Página 123 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Respuesta Laboratorio 9. Programación MultiThread

public class ProbadorSubprocesos {

public static void main( String [] args )


{
// crear y nombrar a cada subproceso
ImprimirSubproceso subproceso1 = new ImprimirSubproceso( "subproceso1" );
ImprimirSubproceso subproceso2 = new ImprimirSubproceso( "subproceso2" );
ImprimirSubproceso subproceso3 = new ImprimirSubproceso( "subproceso3" );

[Link]( "Iniciando subprocesos" );

[Link](); // iniciar subproceso1 y colocarlo en estado listo


[Link](); // iniciar subproceso2 y colocarlo en estado listo
[Link](); // iniciar subproceso3 y colocarlo en estado listo

[Link]( "Subprocesos iniciados, termina main\n" );

} // fin de main

} // fin de la clase ProbadorSubprocesos

// la clase ImprimirSubproceso controla la ejecución de los subprocesos


class ImprimirSubproceso extends Thread {
private int tiempoInactividad;

// asignar nombre a subproceso, llamando al constructor de la superclase


public ImprimirSubproceso( String nombre )
{
super( nombre );

// elegir tiempo de inactividad aleatorio entre 0 y 5 segundos


tiempoInactividad = ( int ) ( [Link]() * 5001 );
}

// el método run es el código a ejecutar por el nuevo subproceso


public void run()
{
// colocar subproceso en inactividad durante el tiempo indicado por tiempoInactividad
try {
[Link](
getName() + " va a estar inactivo durante " + tiempoInactividad );

[Link]( tiempoInactividad );
}

// si el subproceso se interrumpió durante su inactividad, imprimir rastreo de la pila


catch ( InterruptedException excepcion ) {
[Link]();
}

Programacion Java Página 124 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

// imprimir nombre del subproceso


[Link]( getName() + " termino su inactividad" );

} // fin del método run

} // fin de la clase ImprimirSubproceso

Programacion Java Página 125 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Respuestas Laboratorio 10. JDBC

Código de Creación de la Tabla


[Link]("CREATE TABLE contacto (id INT AUTO_INCREMENT, PRIMARY KEY(id), nombre
VARCHAR(20), apellidos VARCHAR(20), telefono VARCHAR(20))");

Código de Inserción de datos:

String nombres[]={"Juan","Pedro","Antonio"};
String apellidos[]={"Gomez","Lopez","Alvarez"};
String telefonos[]={"123","456","789"};
...
for (int i=0;i<[Link];i++)
[Link]("INSERT INTO contacto (nombre, apellidos, telefono) VALUES
('"+nombres[i]+"','"+apellidos[i]+"','"+telefonos[i]+"' )");

Código para Consulta de los Datos

ResultSet rs = [Link]("SELECT * FROM contacto");


while ([Link]())
{
[Link]("nombre="+[Link]("nombre")+
", apellidos="+[Link]("apellidos")+
", telefono="+[Link]("telefono"));
}
[Link]();

Código para actualizar datos:

rs = [Link]("SELECT id FROM contacto WHERE nombre='Juan'");


[Link]();
int id = [Link]("id");
[Link]("UPDATE contacto SET telefono='111' WHERE id="+id);

Código para la consulta:

public class PruebaMySQL {

public PruebaMySQL()
{
// Se mete todo en un try por los posibles errores de MySQL
try
{
// Se registra el Driver de MySQL
[Link](new [Link]());
Connection conexion = [Link] (
"jdbc:mysql://localhost/prueba","root", "la_clave");

Programacion Java Página 126 de 18


Dirección de Operación
Centro Nacional de Capacitación Sureste

Statement s = [Link]();

ResultSet rs = [Link] ("select * from persona");

while ([Link]())
{
[Link] ([Link] ("Id") + " " + [Link] (2)+
" " + [Link](3));
}

[Link]();
}
catch (Exception e)
{
[Link]();
}
}

public static void main(String[] args)


{
new PruebaMySQL();
}

Código para borrar datos

rs = [Link]("SELECT id FROM contacto WHERE nombre='Pedro'");


[Link]();
id = [Link]("id");
y ahora lo borramos
[Link]("DELETE FROM contacto WHERE id="+id);

Programacion Java Página 127 de 18

También podría gustarte