Curso - Java
Curso - Java
CURSO
Caracas, 2006
Elaborado por:
- Prof. Castañeda, Marbella
- Prof. Hidalgo, Erika
- Prof. Ramos, Darwin
- Prof. Rivas, Ronel
Caracas, 2005
Tema V. Entrada/Salida
OBJETIVOS:
CONTENIDO:
Java vs C/C++
La plataforma Java
Identificadores
Operadores de Java
Estructuras de Control
............................
4
Curso de Java Standard Edition – J2SE 4
1. ORÍGENES DEL LENGUAJE
La creación y desarrollo de los lenguajes de programación se rige por dos factores básicos: el
perfeccionamiento del arte de programar y agregar cambios al ámbito de la computación.
El lenguaje de programación Java no es una excepción, ya que se genera partiendo del extenso
legado de C y C++, y agrega refinamiento y características que reflejan el estado actual de la
programación. Este lenguaje fue concebido por James Gosling, Patrick Naughton, Chris Warth, Ed
Frank y Mike Sheridan para Sun Microsystems, en 1991. Se le llamó inicialmente “Oak” pero después
en 1995, se renombró como Java.
La razón más importante para la creación de este lenguaje era la necesidad de crear un lenguaje
independiente de la plataforma y que se pudiera usar para crear software incorporable en
dispositivos electrónicos, como televisores, hornos microondas, neveras, etc. En la búsqueda de
una solución, se trabajó en un lenguaje portátil de plataforma cruzada que generase códigos que se
pudiesen ejecutar en distintos CPU para diversos ambientes.
Como se puede observar la motivación inicial de Java no era la Internet, pero a pesar de esto, el
mismo está fuertemente ligado a la red, ya que mientras se elaboraban los detalles de Java,
apareció un factor que jugaría un papel crucial en el futuro de este lenguaje: La World Wide Web. El
equipo de desarrolladores de Java observó que este nuevo entorno presentaba los mismos
requerimientos que ellos perseguían cubrir con Java: programas de código pequeño, confiable,
seguro e independiente de la plataforma. Si el mundo Web no hubiese tomado forma a la vez
que se estaba implementado Java, Java podría haber sido un lenguaje útil pero dedicado a la
programación de dispositivos electrónicos para el consumo.
Java es en esencia un lenguaje de programación orientado a objetos. Sin embargo, Java no es solo
un lenguaje de programación, sino que también define una plataforma en la que las aplicaciones
pueden ser desarrolladas y ejecutadas.
El diseño de Java es tal que, es multiplataforma en código fuente y la forma binaria compilada. Esto
es posible, ya que Java compila su código fuente en un bytecode intermedio e independiente de la
plataforma. Este bytecode es interpretado usando un intérprete específico de la plataforma, es decir
la Máquina Virtual de Java (Java Virtual Machine – JVM) en tiempo de ejecución del programa.
A continuación se presentan las principales características que han convertido a Java en un lenguaje
sumamente popular.
- Simple: Java es bastante fácil de aprender, dado que tiene la sintaxis de C/C++. Es muy fácil
que un programador experimentado la domine, ya que solo se necesita una comprensión
apropiada de los conceptos de programación orientada a objetos. Además de su similitud con
C/C++, Java tiene otra característica que lo hace simple, y es que Java hace un esfuerzo por no
tener características sorprendentes. En Java hay un número reducido de formas claras para
abordar una tarea dada.
- Orientado a Objetos: Java no se creó para ser compatible en código fuente con otros
lenguajes. Esto otorgó a los desarrolladores de Java la libertad de diseñar un lenguaje partiendo
de cero. El resultado de esto fue una aproximación limpia, útil y pragmática a los objetos, en un
lenguaje puramente orientado a objetos. El modelo de objetos Java es simple y fácil de ampliar,
mientras los tipos simples permanecen como “no objetos” de alto rendimiento.
- Portable: Java, usa un conjunto optimizado de instrucciones, diseñado para ser ejecutado por
una Máquina Virtual, que es emulada por el sistema en tiempo de ejecución de Java. Este
conjunto de instrucciones se conoce como BYTECODE, que representa la salida de un compilador
de Java. Esto significa que el sistema de tiempo de ejecución de Java es un Intérprete de
BYTECODE. Debido a esto, sólo el sistema de tiempo de ejecución de Java tiene que ser
implementado para cada plataforma, y una vez que este paquete existe para un sistema,
cualquier programa Java puede correr en él.
- Interpretado y de Alto Rendimiento: Java fue diseñado para ser un lenguaje interpretado, a
fin de solucionar los aspectos relacionados con la descarga a través de la Internet. Ejecutar
programas de Java en diferentes entornos es una tarea simple debido a que estos programas
(BYTECODE) son Interpretados por una Máquina Virtual Java. A pesar de que el BYTECODE de Java
es interpretado, está diseñado de tal forma que fácil de traducir a código máquina nativo para
alto rendimiento.
- Seguro: Una de las principales características de Java, es que la ejecución de un programa Java
está limitada al entorno de ejecución Java, por lo que no se proporciona acceso a partes
restringidas del computador. Esto lo garantiza la característica de ser un lenguaje interpretado,
ya que el sistema de tiempo de ejecución puede contener un programa y evitar que produzca
efectos colaterales fuera del sistema, obedeciendo al hecho que la Máquina Virtual controla la
ejecución de cada programa Java.
- Robusto: Siendo un lenguaje estrictamente tipificado, Java verifica el código del programador
en tiempo de compilación, y además en tiempo de ejecución. Java da una alta prioridad a la
capacidad de generar programas confiables, a fin de enfrentar las extraordinarias demandas
provenientes del entorno multiplataforma de Internet.
- Multihilo: Java fue diseñado para cumplir el requisito del mundo real de crear programas env
red interactivos. Para conseguir esto, Java proporciona la programación multihilo, que permite
escribir programas que realicen varias cosas a la vez. El intérprete Java permite la sincronización
de multiprocesos, que permite la construcción de programas interactivos, que se ejecuten
eficientemente.
- Dinámico: En Java el código puede ser enlazado dinámicamente en forma segura. Esto es
posible por las grandes cantidades de data en tiempo de ejecución que procesan los programas
de Java, que es usada para la verificación y resolución de accesos a objetos en tiempo de
ejecución. Esta característica es importante para la robustez del entorno de applets, y hace
posible actualizar dinámicamente pequeños bits del BYTECODE en un sistema en plena ejecución.
4. JAVA vs C/C++
Comparado con C++, Java es considerado un lenguaje puramente orientado a objetos, debido a que
los programas Java requieren necesariamente el uso de objetos y no como en C++, en donde se
pueden escribir programas híbridos. En Java no existen funciones ni variables globales; todas las
interfaces con data de objetos deben ser definidas en las bibliotecas de clases.
Java omite muchas características de difícil comprensión de C++. Estas características omitidas
consisten principalmente en la sobrecarga de operadores, la herencia múltiple y las conversiones
automáticas extensivas.
5. LA PLATAFORMA JAVA
Una plataforma se define como el entorno de hardware y/o software sobre el cual se ejecutan los
programas. La plataforma Java es una plataforma de sólo software, que se ejecuta sobre cualquier
otra plataforma basada en hardware. Java posee tres grandes plataformas: la J2SE (Java 2 Platform
Standard Edition), la J2EE (Java 2 Platform Enterprise Edition) y la J2ME (Java 2 Platform Micro
Edition).
HERRAMIENTAS/UTILIDADES DE DESARROLLO
TECNOLOGÍAS DE DESPLIEGUE
API
Interfaces de
Núcleo Integración
Usuario
Componentes a utilizar
Plataformas
SOLARIS LINUX WINDOWS OTRO
- Básicas: herramientas fundamentales del SDK que se usan para crear y construir
aplicaciones. Algunas de las herramientas básicas que usaremos en este curso se describen
a continuación:
- RMI: herramientas que te permiten crear aplicaciones que interactúan entre redes, tales
como la Web.
- IDL y RMI-IIOP: herramientas utilizadas para crear aplicaciones que usen el estándar
OMG IDL y CORBA/IIOP.
En la base de cualquier lenguaje de programación están sus tipos de datos y operadores, y java no
es la excepción. Los tipos de datos son importantes en Java, porque este es un lenguaje
fuertemente “tipeado”. Esto significa que todas las expresiones tienen algún tipo cuya
compatibilidad es verificada por el compilador.
Java contiene dos categorías generales de tipos de datos incorporados: el orientado a objetos y el
no orientado a objetos. Los tipos de Java orientado a objetos son definidos por clases y los no
orientados a objetos, son los que nosotros llamamos tipos de datos simples.
- Tipos de datos simples: Estos tipos de datos son también llamado elementales o
primitivos y a partir de éstos, pueden ser construidos otros tipos de datos. Java especifica
un rango estricto y un comportamiento para cada tipo simple, que deben soportar las
implementaciones de la Máquina Virtual de Java. Por ejemplo, una variable de tipo “int” es
igual en todos los entornos de ejecución. Esto permite que los programas sean
transportables. Los tipos simples permitidos en Java son:
VALOR
TIPO SIGNIFICADO # BITS RANGO
INICIAL
boolean Representa valores true/false 16 true / false false
char Carácter (Unicode) 16 0 a 65.536 ‘\u0000’
float Real de simple precisión 32 1,7e-308 a 1,7e+308 0.0f
double Real de doble precisión 64 3,4e-38 a 3,4e+38 0.0
byte Enteros de 8 bits 8 -128 a 127 0
short Entero corto 16 -32.768 a 32.767 0
int Entero 32 -[Link] a [Link] 0
long -[Link].854.775.808
Entero largo 64 [Link].854.775.807
0L
Cuando se mezclan tipos compatibles en una asignación, el valor del lado derecho
es automáticamente convertido al tipo del lado izquierdo. De modo que en el
ejemplo anterior, el valor de i es convertido en float y luego asignado a f. Sin
Cuando se cumplen estas dos condiciones, tiene lugar una conversión implícita. Por
ejemplo, el tipo int siempre es suficientemente grande como para almacenar todos
los valores byte. Un long a double es una conversión implícita que es
automáticamente desarrollada. No hay conversión implícita de los tipos numéricos a
char o boolean. Tampoco char y boolean son compatibles entre si. Sin embargo, un
literal entero puede ser asignado a char.
- Tipos de datos orientados a objetos: Estos tipos de datos son clases construidas a
partir de los tipos de datos simples. Java especifica un conjunto de clases que permiten
realizar programas Java 100% orientados a objetos, y esto es lo que hace a los programas
transportables. Los tipos orientados a objetos proporcionados en Java, se encuentran
almacenados en paquete [Link], y éstos son:
o Object: Object es la superclase de todas las demás clases, representa la clase más
arriba en la jerarquía de todos los objetos en Java. Algunos de los métodos que
define la clase Object y que están disponibles para todos los objetos son:
MÉTODO DESCRIPCIÓN
Crea un nuevo objeto idéntico al objeto que llama
Object Clone() Throws Throwable
al método.
Devuelve true si el objeto que llama método es
boolean equals(Object objeto)
equivalente a objeto.
Método finalize() por omisión. El método finalize
void finalize () throws Throwable
es semejante a los destructores.
Obtiene un objeto Class que describe el objeto
final Class getClass()
que declara el método.
String toString() Devuelve una cadena que describe al objeto.
MÉTODO DESCRIPCIÓN
MÉTODO DESCRIPCIÓN
Devuelve true si Ch está definido por Unicode,
Static Boolean IsDefined(char Ch)
en caso contrario, devuelve false.
Devuelve true si Ch es un dígito, devuelve
Static Boolean IsDigit(char Ch)
false.
Devuelve True si Ch es una letra, en caso
Static Boolean IsLetter(char Ch)
contrario devuelve False.
Devuelve True si Ch es una letra o un dígito, en
Static Boolean IsLetterOrDigit(char Ch)
caso contrario devuelve False.
Devuelve True si Ch es una letra minúscula, en
Static Boolean IsLowerCase(char Ch)
caso contrario devuelve False.
Devuelve True si Ch es un espacio en blanco,
Static Boolean IsSpace(char Ch)
en caso contrario devuelve False.
Devuelve True si Ch es carácter de título
Static Boolean IsTitleCase(char Ch)
Unicode, en caso contrario devuelve False.
Devuelve True si Ch es una letra mayúscula, en
Static Boolean IsUpperCase(char Ch)
caso contrario devuelve False.
Static char toLowerCase (char Ch) Devuelve la letra minúscula equivalente a Ch
Static char toTitleCase (char Ch) Devuelve la letra de título equivalente a Ch
Static char toUpperCase (char Ch) Devuelve la letra mayúscula equivalente a Ch
MÉTODO DESCRIPCIÓN
Devuelve el valor especificado como un int.
public abstract int intValue()
Este método puede involucrar redondeo.
Devuelve el valor especificado como un long.
public abstract long longValue()
Este método puede involucrar redondeo.
Devuelve el valor especificado como un float.
public abstract float floatValue()
Este método puede involucrar redondeo.
Devuelve el valor especificado como un double.
public abstract double doubleValue()
Este método puede involucrar redondeo.
Devuelve el valor especificado como un short.
public short shortValue()
Este método puede involucrar redondeo.
o Integer: esta clase es una envoltura para los tipos de datos simples int, short y
byte. Los constructores para la clase Integer son:
Integer (int)
Integer (String) throws NumberFormatException
Esta clase define las constantes MIN_VALUE y MAX_VALUE, que establecen el rango
de valores que puede representar un objeto de esta clase. A continuación se
muestran estos métodos:
MÉTODO DESCRIPCIÓN
Devuelve true si el objeto Integer que lo llama
boolean equals (Object objInteger)
es equivalente a objInteger
Devuelve un valor entero equivalente al número
static int parseInt (String)
contenido en la cadena str.
Devuelve un valor entero equivalente al número
static int parseInt (String, int)
contenido en la cadena str usando la base.
Devuelve un Integer que contiene el valor
static Integer valueOf (String)
especificado por la cadena str.
Devuelve un Integer que contiene el valor
static Integer valueOf (String, int) especificado por la cadena str usando la base
indicada.
Todos estos métodos arrojan la excepción “NumberFormatException”
o Long: esta clase es una envoltura para los tipos de datos simples int, short y byte.
Los constructores para la clase Long son:
Long (int)
Long (String) throws NumberFormatException
Esta clase define las constantes MIN_VALUE y MAX_VALUE, que establecen el rango
de valores que puede representar un objeto de esta clase. A continuación se
muestran estos métodos:
o Double: esta clase es una envoltura para el tipo de dato simple double. Los
constructores para la clase Double son:
Double (int)
Double (double)
Double (String) throws NumberFormatException
Esta clase define las constantes MIN_VALUE y MAX_VALUE, que establecen el rango
de valores que puede representar un objeto de esta clase. Igualmente define las
constantes NaN (No es número), POSITIVE_INFINITY (Infinito Positivo) y
NEGATIVE_INFINITY(Infinito Negativo). A continuación se muestran estos métodos:
MÉTODO DESCRIPCIÓN
Devuelve true si el objeto Double que lo llama
boolean equals (Object objDouble)
es equivalente a objDouble
Devuelve true si el objeto contiene un valor
boolean isInfinite ()
infinito. En caso contrario, devuelve false.
Devuelve true si num contiene un valor
static boolean isInfinite(float num)
infinito. En caso contrario, devuelve false.
Devuelve true si el objeto contiene un valor
boolean isNaN () que no es número. En caso contrario, devuelve
false.
Devuelve true si num contiene un valor que no
static boolean isNaN (float num) es un número. En caso contrario, devuelve
false.
Devuelve un objeto Double que contiene el
static Double valueOf (String str)
valor especificado por la cadena String
static double parseDouble(String str) Devuelve un valor double equivalente al
número contenido en la cadena str.
Todos estos métodos arrojan la excepción “NumberFormatException”
o Float: esta clase es una envoltura para el tipo de dato simple float. Los
constructores para la clase Float son:
Esta clase define las constantes MIN_VALUE y MAX_VALUE, que establecen el rango
de valores que puede representar un objeto de esta clase. Igualmente define las
constantes NaN (No es número), POSITIVE_INFINITY (Infinito Positivo) y
NEGATIVE_INFINITY(Infinito Negativo). A continuación se muestran estos métodos:
MÉTODO DESCRIPCIÓN
Devuelve true si el objeto Float que lo llama es
boolean equals (Object objFloat)
equivalente a objFloat
Devuelve true si el objeto contiene un valor
boolean isInfinite ()
infinito. En caso contrario, devuelve false.
Devuelve true si num contiene un valor
static Boolean isInfinite (float num)
infinito. En caso contrario, devuelve false.
Devuelve true si el objeto contiene un valor
boolean isNaN () que no es número. En caso contrario, devuelve
false.
Devuelve true si num contiene un valor que no
static Boolean isNaN (float num) es un número. En caso contrario, devuelve
false.
Devuelve un objeto Float que contiene el valor
static Float valueOf (String str)
especificado por la cadena String
Devuelve un valor float equivalente al número
static float parseFloat (String str)
contenido en la cadena str.
Todos estos métodos arrojan la excepción “NumberFormatException”
o Boolean: esta es una envoltura muy simple alrededor de valores boolean que sólo
es útil cuando se quiere pasar una variable bolean por referencia. Esta clase
contiene las constantes TRUE y FALSE, que definen un objeto Boolean true y false.
A continuación se muestran constructores de esta clase:
Boolean (boolean ValorBoolean)
Boolean (String CadenaBoolean)
Inicialización de un arreglo:
Cuando un arreglo es construido en Java, sus elementos son inicializados
automáticamente con los valores por omisión, en caso de no haber una
inicialización explicita.
int ints[] = new int []{10,20,30,40};
double [] reales = new double [3]; Æ Todos los elementos del arreglo con 0.0d
7. IDENTIFICADORES
Los identificadores usados en Java siguen reglas estándar: comienzan con una letra y pueden
contener sólo letras, números, los caracteres underscore (_) y dólar ($). Además no deben incluir
espacios. No existe restricción de longitud para los identificadores de Java. Los identificadores en
Java son sensibles a mayúsculas y minúsculas.
- Alcance y Bloques. Al igual que en C y C++, Java también usa los caracteres { y } para
marcar el inicio y el final del bloque de sentencia(s). Una variable declarada dentro del
bloque sólo puede usarse dentro de ese bloque o en cualquier bloque que esté anidado en
él. La variable no estará disponible una vez que el control del programa salga del bloque en
el que fue declarada.
Java tiene seis clases generales de operadores: aritméticos, a nivel de bits, relacionales y lógicos.
Java también define algunos operadores adicionales que permiten controlar ciertas situaciones
especiales.
- Operadores Aritméticos: Los operadores +, -,* y /, pueden ser aplicados a cualquier tipo
de datos numéricos, así como también, a los tipos char.
- Operador instanceof: permite conocer si una variable de objeto está instanciada con un
tipo de objeto específico. La forma Genaro de este operador es como sigue:
PRIORIDAD OPERADORES
() [ ] .
MAYOR ++ -- !
* / %
+ -
>> >>> <<
>= >= < <=
. == !=
. &
. ^
|
&&
||
?:
MENOR = OP=
Las estructuras de control permiten realizar asignaciones, documentar el código, así como
también permiten tomar decisiones y realizar procesos repetidas veces, por lo que éstas
se clasifican en dos amplias categorías Condicionales e Iterativas. Estas en Java, son
básicamente las mismas sentencias que existen C/C++, solo con algunas consideraciones
especiales.
if (COND) {
...
} else {
...
}
switch(var){
case valor1: { … }
case valor2: { … }; break;
…
default: { … }
}
while (COND) {
...
}
do {
...
} while (COND);
- Sentencia break: Las sentencia break ocasiona que el flujo de control salte a
sentencia inmediatamente siguiente a la sentencia actual (rompe la ejecución). La
sentencia break se puede emplear tanto en las sentencias condicionales como en
las iterativas.
OBJETIVOS:
CONTENIDO:
Clases
Objetos
Paquetes
............................
22
Curso de Java Standard Edition – J2SE 22
1. CLASES
La clase es núcleo de Java. Es la construcción lógica sobre la que se construye el lenguaje Java, ya
que define la forma y la naturaleza de un objeto. La clase constituye la base de la Programación
Orientada a Objetos en Java. Cualquier concepto que desee implementar en un programa Java debe
ser encapsulado en una clase. Dentro de una clase están definidos los datos y los códigos que
actúan sobre esos datos. Todas las actividades del programa Java ocurren dentro de una
clase, razón por la cual se dice que Java es un lenguaje 100% orientado a objetos.
Una clase en Java se define como: “una plantilla que tiene las definiciones de variables o estados y
métodos o comportamientos que es común a todos los objetos de un tipo en particular”. Java usa
especificaciones de clase para construir objetos, que son instancias de una clase. De tal manera,
una clase es básicamente un juego de planos que especifican cómo construir un objeto. Es
importante tener claro que una clase es una abstracción lógica, por lo que hasta que un objeto de
esa clase sea creado, no existirá una representación física de esa clase en memoria.
Los miembros de la clase, es decir los atributos y los métodos son llamados respectivamente
variables de instancia y métodos de instancia; ya que estos representan el estado de un
objeto, es decir que cada objeto de una clase contiene una copia propia de esas variables,
separada a la de los otros objetos de la clase. Además, existen las variables y métodos de clase,
los cuales pueden ser accedidos directamente de una clase sin instanciar, es decir que son
comunes a todos los objetos de una clase por igual.
Cuando se define una clase, se manifiesta su naturaleza y forma exacta. Esto se hace especificando
los miembros de la clase, es decir las variables y los métodos que operan en ella.
Una clase se define a través de la palabra clave class. A continuación se muestra la forma general
de la definición de una clase:
// Variables miembro
[acceso] [modif] tipo nombreVariable [= valorInicial];
CUERPO DE LA CLASE
// Métodos miembro
[acceso] [modif] tipo nombreMetodo([parametros]) [throws excepciones]{
// Cuerpo del método
};
};
COMPONENTES PROPÓSITO
COMPONENTES PROPÓSITO
Cuando el sistema encuentra una clase por primera vez en un programa, crea una única copia
de todas las variables de clase que serán compartidas por todas las instancias (objetos) de la
clase. Si una variable de clase es cambiada por un objeto de la clase, entonces el cambio de su
valor se refleja en todas las demás instancias de la clase.
COMPONENTES PROPÓSITO
Ya que Java es un lenguaje netamente orientado a objetos, cuando sea necesario implementar
funciones para uso general, la forma de hacerlo es a través de los métodos de clase (static).
- Especificadores de acceso
Podemos usar los especificadores de acceso a Java para proteger las variables y métodos de
una clase mientras se declaran. La siguiente tabla presenta los niveles de accesos permitidos:
ESPECIFICADOR SIGNIFICADO
Accedida por la clase en donde está definida, sus subclases y las clases en
protected
el mismo paquete
float Y;
static char sc;
class Ejemplo
static double sd; {
… sc VARIABLES sv
} DE CLASE
// Métodos Miembro
void setX(int valor) {
x=valor;
x VARIABLES
};
Variables y
DE INSTANCIA
public float getY() {
Objetos Objeto
return Y;
};
};
Como ya se ha mencionado en Java todo es una clase, por lo tanto la aplicación (programa) también
es una clase. Dicha clase tiene la característica particular de poseer un método de clase denominado
main. Este método es semejante a la función main() de un programa C++, razón por la cual, va a
ser el primer método en ejecutarse al correr un programa Java.
...
// Método main
public static void main(String [ ] args) {
// Cuerpo del método
};
…
};
Otra característica importante de las clases ejecutables, es que la misma debe ser public y llamarse
igual al archivo que la contiene, es decir el nombre del archivo fuente (archivo .java) debe ser el
idéntico al nombre de la clase.
Usualmente, en un programa Java, se crean muchos objetos a partir de diferentes clases y estos
interactúan entre ellos enviando mensajes. Después de que el objeto completa el trabajo para el
cual se creó, se recolecta como basura y sus recursos se liberaron, para el uso de otros objetos. El
ciclo de vida de un objeto consiste típicamente de los siguientes pasos: creación de objetos, uso de
los objetos creados y destrucción de los objetos.
Cuando se crea una clase se está creando un nuevo tipo de dato que se puede utilizar para declarar
objetos de ese tipo. Sin embargo, para obtener objetos de una clase es necesario hacer dos pasos.
En primer lugar, se debe declarar una variable del tipo de la clase. Esa variable no define un objeto,
sino que es simplemente una variable que puede referirse a un objeto. En segundo lugar, se debe
obtener una copia física y real del objeto y asignarla a la variable.
En realidad, en la sentencia dada se realizan tres acciones: la declaración del objeto, la instanciación
del objeto y la inicialización del mismo. La declaración del objeto no necesita realizarse junto con la
creación del objeto. Pueden hacerse en pasos separados como se muestra a continuación:
Coordenadas plano;
plano = new Coordenadas();
Aquí la primera de las dos líneas es la declaración del objeto, en donde Coordenadas representa a la
clase y plano es la variable de referencia a los objetos. El operador new en Java es llamado
operador de instanciación, el cual se usa para crear nuevos objetos. La inicialización del objeto
se hace usando Coordenadas(), que es la llamada a su constructor usado para inicializar el objeto.
- Constructores de una clase: Todas las clases en Java tienen al menos un constructor
para inicializar un objeto nuevo creado a partir de un tipo en particular. El nombre del
constructor es el mismo que el nombre de la clase, no tiene tipo de retorno y debe ser
público. Java nos permite tener tantos constructores como queramos para una clase
(sobrecarga del constructor). Mientras creamos nuestra propia clase, no necesitamos
escribirle un constructor, ya que el sistema en tiempo de ejecución proporciona un
constructor por omisión para la clase si nosotros no desarrollamos ninguno. Este constructor
por omisión, tiene una implementación vacía.
Una vez que se crea un objeto, nos gustaría usarlo para realizar alguna tarea. Podemos necesitar
alguna información del objeto, podemos querer cambiar su estado, o podemos querer usarlo para
realizar alguna tarea. Hacemos estas cosas ya sea manipulando o visualizando sus variables o
llamando a sus métodos. En fin, el uso de los objetos está limitado a invocar a los métodos
miembros de la clase a la cual pertenecen, y a cambiar de referencia.
Objeto.Método(parámetros);
Supongamos que la clase Coordenada, posee un método para asignar y obtener la coordenada x, su
implementación e invocación sería como sigue:
Los objetos están dinámicamente asignados en una sección de memoria libre por medio del
operador new. Como sabemos, la memoria no es infinita y la memoria libre puede agotarse. Por
esta razón, un componente clave para cualquier esquema de asignación dinámica de memoria,
consiste en recobrar la memoria libre de objetos que no estén en uso, disponiendo de esta memoria
para reasignaciones posteriores. En muchos lenguajes de programación, el liberar memoria asignada
con anterioridad se hace manualmente. Por ejemplo, en C++ se usa el operador delete para liberar
memoria que estaba asignada. Sin embargo, Java emplea un método diferente: recolección de
basura.
3. PAQUETES
En programación, los paquetes, son útiles para agrupar las piezas relacionadas de un programa. En
Java, un paquete sirve para dos propósitos: primero, suministra un mecanismo por el cual piezas
relacionadas de un programa pueden ser organizadas como una unidad; así, un paquete
proporciona la manera de nombrar una colección de clases. Segundo, un paquete participa en los
mecanismos de control de acceso en Java. Las clases definidas dentro de un paquete pueden
hacerse privadas a ese paquete y no accesibles por código fuera del paquete.
Es importante aclarar, que a los paquetes hay que considerarlos desde dos puntos de vista: el punto
de vista lógico, en el cual los paquetes almacenan las declaraciones de las clases (archivos fuente de
Java); y el punto de vista físico, en el cual los paquetes van a almacenar los archivos .class de las
clases definidas dentro del paquete.
En general, cuando nombra una clase, está asignando un nombre desde el espacio de nombre.
Un espacio de nombre define una región declaratoria. En Java dos clases no pueden usar el mismo
nombre desde el mismo espacio. Así, dentro de un espacio de nombre dado, cada nombre de clase
debe ser único. Los paquetes suministran una manera de dividir el espacio de nombre, evitando
problemas de duplicidad de nombres. Cuando una clase se define dentro de un paquete, el nombre
de ese paquete se une a cada clase, con lo que se evita que los nombres choquen con otras clases
del mismo nombre, pero que estén en otros paquetes. Si Para una clase, no se define un paquete,
dicha clase pertenecerá al paquete predeterminado de Java y por ende al espacio de nombre
predeterminado o global de Java.
Todas las clases en Java pertenecen a algún paquete. Como se mencionó anteriormente, cuando no
se especifica algún paquete se usa el paquete predeterminado (o global). Además, el paquete
predeterminado no tiene nombre, lo que lo hace transparente.
Para crear un paquete, coloque un comando package como la primera sentencia del archivo fuente
de Java. Esto asegurará que cualquier clase declarada en ese archivo pertenecerá a ese paquete
particular. Debido a que un paquete define un espacio de nombre, los nombres de las clases que
coloque dentro del archivo fuente, se convierten en parte de ese espacio del paquete. Una misma
sentencia package se puede incluir en más de un archivo fuente, por lo que no se impide que otras
clases de otros archivos puedan formar parte de un mismo paquete. En las aplicaciones reales, los
paquetes se suelen distribuir en muchos archivos fuente.
Java usa el sistema de archivo para manejar los paquetes, con cada paquete almacenado en su
propio directorio. Como el resto de Java, los nombres de paquetes son sensibles a mayúsculas y
minúsculas. Es decir, el directorio en el cual es guardado un paquete debe ser el mismo del nombre
del paquete.
package myPack;
Este paquete corresponderá con un directorio en el sistema de archivos llama \myPack. Observe que
se puede crear una jerarquía de paquetes dentro de paquetes separando los niveles con puntos.
package paq1.paq2.paq3;
Esta jerarquía de paquetes se debe reflejar en el sistema de archivos del sistema de desarrollo de
Java: \paq1\paq2\paq3.
Como se explicó, los paquetes son reflejados en directorios. ¿Cómo sabe el sistema en tiempo de
ejecución de Java dónde buscar los paquetes que usted creó? La respuesta tiene dos partes.
Primero, por omisión: el sistema en tiempo de ejecución de Java busca en el directorio en curso
como punto de partida. Así, si sus archivos de clase están en el directorio actual, o en un
subdirectorio del directorio actual, ellos se encontrarán. Segundo, puede especificar una ruta o rutas
de directorios, colocándola en la variable de entorno CLASSPATH. Dicha variable, controla la
ubicación particular que debe ser considerada por Java como la raíz de la jerarquía de paquetes.
Para configurar esta variable de entorno, desde la consola del sistema escribir lo siguiente:
[set] CLASSPATH=.;CLASSPATH[;otros_directorios]
Java proporciona muchos niveles de protección para permitir un control adecuado de la visibilidad
de las variables y métodos dentro de clases, subclases y paquetes. Las clases y los paquetes son
dos medios de encapsular y contener el espacio de nombre y alcance de las variables y métodos.
Java proporciona cuatro tipos de visibilidad para los miembros de clase. Visibilidad de los miembros
de la clase según su modificador de acceso.
private Si No No No
protected Si Si Si No
public Si Si Si Si
package Si No Si No
Dado que los paquetes existen y son un buen mecanismo para organizar de forma estructurada las
clases, es fácil de ver por qué todas las clases incorporadas en Java se almacenan en paquetes. No
hay ninguna clase de Java almacenada en el paquete por omisión.
De manera análoga, a lo que sería una directiva #include en C++, Java incluye la sentencia
import, para que se puedan ver ciertas clases o paquetes enteros. En un archivo fuente de Java,
las sentencias import tienen que ir inmediatamente después de la sentencia package, si existe, y
antes de las definiciones de las clases.
A continuación estudiaremos los paquetes de mayor relevancia que proporciona la API de Java.
Nota: las clases en cursiva fueron vistas en los tipos de datos orientados a objetos (Tema
I). En esta parte se estudiaran las clases resaltadas en negrita.
MÉTODO DESCRIPCIÓN
Devuelve la hora actual en milisegundos
static long currentTimeMillis ()
desde el 1 de enero de 1970
Detiene la ejecución y devuelve el valor
Static void exit(int codSalida) codSalida al proceso padre. El valor cero (0)
indica que ha terminado correctamente.
Static void gc() Inicia el sistema de recolección de basura
Carga la biblioteca dinámica cuyo nombre
Static void loadLibrary(String lib)
está asociado con lib
Inicia la llamada a los métodos finalize() de
Static void runFinalization() todos los objetos no utilizados y que todavía
están sin recolectar
MÉTODO DESCRIPCIÓN
o Date: Representa una fecha y hora. Los métodos más importantes definos en la
clase Date son lo siguientes:
MÉTODO DESCRIPCIÓN
MÉTODO DESCRIPCIÓN
Este constructor crea un vector vacío con
Vector()
capacidad para 10 elementos.
Este constructor crea un vector vacío con
Vector(int N)
capacidad para N elementos.
Este constructor crea un vector vacío con
capacidad para N elementos y cuyo
incremento es incr. El incremento especifica el
número de elementos que se tienen que
Vector(int N, int incr)
reservar cada vez que se aumenta el tamaño
del Vector, si no se especifica incr, entonces el
Vector duplica su tamaño cada vez que se
reserva memoria para él.
final void addElment(Object elm) Añade al Vector el objeto especificado por elm
Final void insertElementAt(Object o, Añade el Objeto al Vector en la posición
int pos) indicada
final int capacity() Devuelve la capacidad del Vector
final int size() Devuelve el numero de elementos en el Vector
final boolean contain(Object obj) Devuelve true si el objeto está en el Vector
final Object elementAt(int pos) Devuelve el Objeto en la posición especificada
final Object firstElement() Devuelve el primer objeto en el Vector
final Object lastElement() Devuelve el ultimo objeto en el Vector
final bolean isEmpty() Devuelve true si el Vector está vacío
Elimina todos los elementos del Vector. Una
final void removeAllElements()
vez ejecutado el tamaño del Vector es cero.
Elimina la primera instancia del objeto en el
final void removeElement(Object o)
Vector
final void removeElementAt(int pos) Elimina el elemento de la posición indicada
final void setElementAt(Object o, int p) Coloca el objeto en la posición indicada
Devuelve la posición de la primera ocurrencia
final int indexOf(Object element) del elemento. Si el objeto no se encuentra
devuelve -1
MÉTODO DESCRIPCIÓN
Stack() Crea una pila vacía
boolean empty() Devuelve true si la pila está vacía
Devuelve el elemento en el tope, pero no lo
Object peek()
retira de la pila
Devuelve el elemento en el tope y lo extrae
Object pop()
de la pila
Object push(Object element) Introduce un elemento en la pila.
- [Link]: El paquete [Link], contiene todas las clases para realizar las operaciones de
Entrada/Salida (E/S). El estudio de estas clases se realizará en el Tema V:
Entrada/Salida.
/**
* ARCHIVO....: [Link]
* @autor.......: Prof. Ronel J. Rivas R.
* @date........: 19/09/2005
* DESCRIPCIÓN: Archivo que contiene la especificación de un ejemplo sobre:
* paquetes, importación de paquetes y clases, clases generales,
* clases Ejecutables, objetos y referencias a objetos
**/
package myPack;
import [Link].*;
import [Link];
/*************************
** CLASES DEL PAQUETE **
*************************/
// Clase para manejar la Hora
class JTime {
// VARIABLES DE INSTANCIA
private int hour, minutes, seconds;
// CONSTRUCTORES
public JTime() {
super();
setHour(12);
setMinutes(0);
setSeconds(0);
};
public JTime(int h,int m,int s) {
super();
setHour(h);
setMinutes(m);
setSeconds(s);
};
// METODOS DE INSTANCIA
public void setHour(int h) {
[Link] = h;
};
public int getHour(){
return [Link];
};
/**********************************
** CLASE PRINCIPAL DEL PAQUETE **
***********************************/
// Clase de Ejemplo
public class Example {
// VARIABLES DE INSTANCIA
private int day, month, year;
private JTime time;
// CONSTRUCTORES
public Example() {
super();
setDate(12,2,2004);
time = new JTime();
};
// METODOS DE INSTANCIA
public void setDay(int d) {
[Link] = d;
};
public int getDay(){
return [Link];
};
public void setMonth(int m) {
[Link] = m;
};
public int getMonth(){
return [Link];
};
public void setYear(int y) {
[Link] = y;
};
// METODO PRINCIPAL
public static void main(String [] args){
Example miEjemplo = new Example();
JTime hora;
[Link](12,2,2004);
[Link](1,15,0);
hora = [Link]();
OBJETIVOS:
CONTENIDO:
Herencia
Clases abstractas
Interfaces
............................
40
Curso de Java Standard Edition – J2SE 40
1. HERENCIA
1.1. FUNDAMENTOS
Sólo puede haber una superclase para cualquier clase que se cree, ya que Java no soporta la
herencia múltiple, es decir varias superclases en una subclase. Sin embargo, se puede crear una
jerarquía de herencia en la que una subclase llegue a ser una superclase de otra subclase. Ninguna
clase puede ser superclase de sí misma.
Para especificar que una clase hereda de otra, la clase que hereda debe usar en su declaración la
palabra clave extends después del nombre de la clase. Esto implica que la subclase extiende la
funcionalidad y características de la superclase. La forma general de declarar una clase que hereda
de una superclase se muestra a continuación:
El siguiente programa es un ejemplo sencillo de herencia, donde se crea una superclase A y una
subclase llamada B.
//Crea una superclase
class A {
private int i;
private int j;
public void setIJ (int x, int y) {
i = x;
j = y;
}
public int getI () {
return i;
}
}
// Clase Ejecutable
public class Acceso {
public static void main (String args[]) {
B subObj = new B();
[Link] (10, 12);
[Link] ();
[Link] (“El total es ” + [Link]());
}
}
Este programa no compila ya que la referencia a la variable j dentro del método sumar () de la clase
B provoca una violación de acceso. Como j es una variable privada sólo es accesible por los otros
miembros de su propia clase. Aunque una subclase hereda todos los miembros de su superclase, no
puede acceder a aquellos miembros de su superclase que hayan sido declarados private. Para
solucionar esto es necesario implementar un método de instancia público que tenga acceso al
miembro privado.
Una referencia al objeto de la superclase puede tener asignada una referencia a cualquier objeto de
sus subclases. Cuando a una variable de referencia a superclase se le asigna la referencia a la
subclase, el acceso será sólo a los miembros que están definidos en la superclase; debido a que la
superclase no conoce acerca de las características especiales añadidas por su subclase. El siguiente
ejemplo ilustra este aspecto, usando las clases A y B del ejemplo anterior (sin error):
// Clase Ejecutable
public class Acceso {
public static void main (String args[]) {
B subObj = new B();
A superObj = new A();
[Link] (10, 12);
[Link] ();
[Link] (“El total es ” + [Link]());
// Asigna una referencia de B a una referencia de A
superObj = subObj;
[Link] (1, 5); // Correcto: el método setIJ() está definido en la superclase
[Link](); // Error: en la clase A no está definido un método sumar()
}
}
Como B es una subclase de A, es posible asignar subObj a superObj. Sólo el tipo de variable
referencia determina los miembros que se pueden acceder, no el tipo de los objetos a los que se
hace referencia. Por lo tanto, la referencia superObj no puede acceder al miembro sumar(), que sólo
está presente en la clase B.
Al trabajar con herencia, es posible que tanto la superclase como la subclase proporcionen sus
propios constructores, donde cada uno tiene la responsabilidad de inicializar su porción del objeto.
Cuando la superclase y la subclase definen juntas constructores, ambos constructores deben ser
ejecutados. En este caso debe usarse la palabra clave de Java, super, que tiene dos formas
generales. La primera llama un constructor superclase. La segunda es utilizada para acceder a un
miembro de la superclase que ha sido ocultado por un miembro de una subclase.
- Uso de super para llamar constructores de superclase: Una subclase puede llamar al
constructor de la superclase utilizando el modificador super de la siguiente forma:
super (lista_de_parámetros);
Aquí, lista_de_parámetros especifica los parámetros del constructor de la superclase. Si
se utiliza el modificador super(), tiene que ser la primera sentencia ejecutada dentro del
constructor de la subclase.
// Clase Ejecutable
public class Acceso {
public static void main (String args[]) {
B obj1 = new B(); // Utiliza el constructor sin parámetros de la subclase y
// el constructor con 1 parámetro de la superclase
B obj2 = new B(2, 3, 0); // Utiliza el constructor con 3 parámetros de la subclase y
// el constructor con 2 parámetros de la superclase
[Link] ();
[Link] (“El total 1 es ” + [Link]());
[Link] ();
[Link] (“El total 2 es ” + [Link]());
}
}
Como se mencionó, es perfectamente aceptable usar una subclase como superclase de otra. Por
ejemplo, dadas tres clases llamadas A, B y C. La clase C puede ser una subclase de B, que es una
subclase de A. Cuando este tipo de situación ocurre, cada subclase hereda todas las características
encontradas en todas sus superclases. En este caso, C hereda todos los aspectos de B y A.
Objeto de A
Objeto de B
Objeto de C
En una jerarquía de clases, los constructores son llamados en orden de derivación, de superclases a
subclases. Además, como super() tiene que ser la primera sentencia que se ejecuta dentro del
constructor de la subclase, este orden es el mismo tanto si se utiliza super() como si no. Si no se
utiliza super() entonces se ejecuta el constructor por omisión o sin parámetros de cada superclase.
El siguiente ejemplo ilustra el orden de ejecución de los constructores:
// Clase A
class A{
//Constructor por omisión de A
A(){
[Link] (“Construyendo A”);
}
}
// Clase B - subclase de A y superclase de C
class B extends A{
//Constructor por omisión de B
B(){
[Link] (“Construyendo B”);
}
}
//Clase C - subclase de B
class C extends B{
//Constructor por omisión de C
C(){
[Link] (“Construyendo C”);
}
}
public class Acceso{
public static void main (String args[]){
C c = new C();
}
}
La salida del programa es la siguiente:
Construyendo A
Construyendo B
Construyendo C
En una jerarquía de clases, si un método en la subclase tiene la misma fima (los mismos nombres
de métodos, tipos de argumentos, tipo de retorno y excepciones que arroja), que el método en la
superclase, entonces el método en la superclase se dice que fue sobrescrito por el método en la
subclase. Cuando se invoca un método sobrescrito desde la subclase, siempre se refiere al método
definido dentro de la subclase. La versión del método que se encuentra en la superclase está oculto
y puede ser accedido usando la palabra super dentro de la subclase.
En caso de que el método en la superclase y la subclase tengan el mismo nombre pero sus firmas
sean diferentes, entonces los métodos se sobrecargan, más no se sobrescriben; por lo tanto el
ACCESO EN
SUBCLASE
SUPERCLASE
private private, package, protected, public
package package, protected, public
protected protected, public
public public
La palabra clave final tiene tres usos: con una variable, con un método y con una clase. Cuando se
usa con una variable, permite crear el equivalente de una constante con nombre. Cuando se usa con
un método, previene la sobrescritura del método. Cuando se usa con una clase, previene que la
clase se herede.
- Uso del modificador final para prevenir sobrescritura: Cuando se desea que un
método no sea sobrescrito, se usa el modificador final en la declaración del método. Al
declarar un método como final en la superclase, no es posible sobrescribirlo en la subclase;
de ocurrir esto, se producirá un error de compilación. El uso del modificador final ayuda a
eliminar la sobrecarga de costo asociado con la llamada del método. Usualmente, el
compilador de Java resuelve la llamada a un método dinámicamente en tiempo de
ejecución; lo que se denomina enlace tardío. Como los métodos finales no pueden
sobrescribirse, una llamada al método final puede ser resuelta en tiempo de compilación; lo
que se denomina enlace temprano.
class A {
private int x, y, w;
public final int sumar () {
setW ( getX() + getY() );
return w;
}
public int getX () {
return x;
}
public int getY () {
return y;
}
public void setW (int n) {
w = n;
}
}
- Uso del modificador final para prevenir herencia: El modificador final se utiliza en la
declaración de una clase para evitar que esta se herede. Cuando la clase se declara como
final, Java declara implícitamente todos los métodos de la clase como final. No es posible
declarar una clase abstracta como final, dado que la clase abstracta no está completa por sí
misma y espera que sus subclases proporcionen las implementaciones completas.
final class A{
private int x;
public void setX (int n){
x = n;
}
public int getX (){
return x;
}
}
class B extends A{ // Error de compilación: no se puede heredar A
...
}
// Superclase Figura
class Figura {
private double dim1;
private double dim2;
// Constructor por omisión
Figura (double a, double b) {
setDim1 (a);
setDim2 (b);
}
// Métodos GET’s y SET’s
public void setDim1 (double x) {
dim1 = x
}
public double getDim1 () {
return dim1;
}
public void setDim2 (double x) {
dim2 = x
}
public double getDim2 () {
return dim2;
}
// Método para calcular el área de la figura (No definido)
public double area () {
[Link] (“El área de la figura no está definida”);
return 0;
}
}
// Clase Rectangulo que extiende a Figura
class Rectángulo extends Figura {
Retangulo (double a, double b) {
super (a, b); // Se inicializa el objeto usando el constructor de la superclase
}
// Sobrescribe el método area para el rectángulo
public double area () {
[Link] (“Dentro del método área para un rectángulo”);
Return getDim1() * getDim2();
}
}
// Clase Ejecutable
public class EncontrarAreas {
public static void main (String args[]) {
Figura f = new Figura (10, 10);
Rectangulo r = new Rectangulo (5, 5);
Triangulo t = new Triangulo (4, 8);
Figura figRef;
FigRef = r;
[Link] (“El área es: ” + [Link]());
FigRef =tr;
[Link] (“El área es: ” + [Link]());
FigRef = f;
[Link] (“El área es: ” + [Link]());
}
}
El modificador abstract puede usarse de dos formas, con una clase y con un método. Cuando una
clase tiene el modificador abstract en su declaración, esta se denomina clase abstracta; lo que
indica que la clase no puede ser instanciada (no se puede crear un objeto de la clase). Cuando el
modificador abstract es usado en la declaración de un método, es llamado método abstracto; en
este caso, el modificador indica que la implementación del método no se proporciona en la clase.
Los métodos abs tractos sólo pueden presentarse dentro de una clase abstracta. Si se incluye
el modificador abstract en la declaración de un método, indica que la clase que herede de esa clase,
tendrá que proporcionar la implementación para este método; si no proporciona la implementación,
entonces esa subclase deberá ser declarada como abstract.
Una clase abstracta sirve para definir el comportamiento genérico de la clase. La clase abstracta
tiene las definiciones de los métodos, que proporcionan el comportamiento de la clase; también
puede implementar algunos de los métodos definidos en la clase, dando una implementación parcial
de su comportamiento.
abstract class X {
// Cuerpo de la clase
…
}
Las clases abstractas se usan cuando se quiere definir una superclase que declara la estructura de
una abstracción sin proporcionar una implementación completa de cada método. Usualmente,
cuando una superclase es incapaz de brindar una implementación significativa para un método,
pueden aplicarse dos soluciones: la primera, simplemente dar un mensaje que se imprima en la
salida estándar; y la segunda, declarar el método como abstracto.
Como es evidente, el cuerpo del método está ausente, lo que significa que la implementación del
método no se proporciona en la clase, y por lo tanto, debe ser implementado por la subclase.
Una clase abstracta puede contener cualquier cantidad de métodos abstractos. Además es posible
que una clase abstracta no tenga ningún método abstracto en ella. Cuando una clase es
declarada como abstracta, no es necesario que la clase contenga métodos abstractos,
pero cuando existe al menos un método abstracto dentro de la clase, esta debe ser
declarada como abstract.
// Superclase Figura
abstract class Figura {
private double dim1;
private double dim2;
// Constructor
Figura (double a, double b) {
setDim1 (a);
setDim2 (b);
}
// Métodos GET’s y SET’s
public void setDim1 (double x) {
dim1 = x;
}
public double getDim1 () {
return dim1;
}
public void setDim2 (double x) {
dim2 = x;
}
public double getDim2 () {
return dim2;
}
// Método para calcular el área de la figura (No implementado)
abstract public double area () {
[Link] (“El área de la figura no está definida”);
return 0;
}
}
// Clase Rectangulo que extiende a Figura
class Rectángulo extends Figura {
Retangulo (double a, double b) {
super (a, b); // Se inicializa el objeto usando el constructor de la superclase
}
// Sobrescribe el método area para el rectángulo
public double area () {
[Link] (“Dentro del método área para un rectángulo”);
Return getDim1() * getDim2();
}
}
// Clase Ejecutable
class EncontrarAreas {
public static void main (String args[]) {
//Figura f = new Figura (10, 10); // Esto no es correcto
Rectangulo r = new Rectangulo (5, 5);
Triangulo t = new Triangulo (4, 8);
Figura figRef; // Esto es correcto
FigRef = r;
[Link] (“El área es: ” + [Link]());
FigRef = t;
[Link] (“El área es: ” + [Link]());
}
}
Las interfaces son sintácticamente igual a las clases, pero sin variables de instancia y sin
implementación para los métodos declarados en ella. La palabra clave interface permite especificar
qué es lo que debe hacer la clase, pero no cómo lo hace. Una interfaz puede ser implementada por
cualquier número de clases. Además, una clase puede implementar cualquier número de interfaces.
Una clase, que implementa una interfaz, debe implementar el conjunto completo de
métodos definidos por la interfaz. Las interfaces actúan como sustitutos para implementar la
herencia múltiple.
interface Contestadora {
void guardarMensaje (String mens);
String getMensaje ();
}
Una vez definida una interfaz, puede ser implementada por una o más clases. Para implementar una
interfaz, es necesario incluir la sentencia implements en la definición de la clase y crear los
métodos definidos por la interfaz.
Si una clase implementa más de una interfaz, las interfaces están separadas con una coma. Si una
clase implementa dos interfaces que declaran el mismo método, la clase da sólo una implementación
para el método. Los métodos que implementan una interfaz deben declarase como
públicos y deben corresponder exactamente, en firma, con los métodos definidos en la
interfaz.
Si una clase incluye una interfaz, pero no implementa todos los métodos definidos por esa interfaz,
entonces esa clase tiene que ser declarada como abstract. Por ejemplo:
Como la clase TeleFax no implementa el método guardarMensaje(String mens) tiene que ser
declarada como abstracta. Cualquier clase que herede de TeleFax, tiene que implementar el
método guardarMensaje(String mens) o ser declarada como abstract.
Es posible aplicar las interfaces para importar constantes compartidas en muchas clases, mediante
una interfaz que declara las variables que son inicializadas con valores deseados. La clase que
implementa la interfaz, incluirá automáticamente todos los nombres de variables como constantes.
Si una interfaz no tiene ningún método, entonces cualquier clase que incluye dicha interfaz no se
tiene que preocupar de implementar nada; realmente, es como importar las variables constantes
declaradas en la interfaz como variables final en la clase que la implementa.
interface Constantes {
int A = 0;
int B = 1;
int C = 2;
}
class X implements Constantes {
int determinarConstante () {
Ambas clases implementaron la interfaz Constantes, donde A, B y C son los enteros definidos. El
valor de estas variables no puede ser cambiado por la clase que implementa la interfaz, pero los
valores que inicializan estas variables están disponibles para las clases que implementes la interfaz,
como si cada clase las hubiese definido o heredado directamente.
Una interfaz puede heredar de otra interfaz usando la palabra clave extends. Esto es similar a la
herencia de clases. Sólo una interfaz puede heredar de otra interfaz; una clase no puede heredar de
una interfaz. Cuando una clase implementa una interfaz que hereda de otra, tiene que implementar
todos los métodos definidos en la cadena de herencia de la interfaz.
interface A {
void metodo1 ();
void metodo2 ();
}
interface B extends A {
void metodo3 ();
void metodo4 ();
}
interface C extends B {
void metodo4 ();
void metodo6 ();
}
interface D {
void metodo6 ();
}
Tanto la interfaz B como la C declaran el mismo método: metodo4 (); a pesar que la interfaz C
hereda el metodo4 () definido en B. Esto es similar a la sobrescritura de métodos en el caso de
clases. La clase PruebaInterfaz implementa las interfaces C y D. La clase tiene que proporcionar la
implementación para los siguientes métodos: metodo1 (), metodo2 (), metodo3(), metodo4() y
metodo6(); debido a que la interfaz C declara implícitamente todos los métodos anteriores, dado
que hereda de las interfaces A y B. Tanto la interfaz C como la D declaran el método: metodo6(),
pero la clase tiene que dar sólo una implementación del método; en caso contrario, ocurre un error
de compilación. Si la clase dejara de dar implementación para alguno de los métodos, esta
tendría que ser declarada como abstract.
Se pueden tener una variable de tipo interfaz, que hagan referencia a una instancia de una clase
que implementa la misma interfaz. Cuando se invoca un método a través de tal referencia, la versión
correcta del método invocado se basará en la instancia actual de la interfaz que es referenciada (se
Curso de Java Standard Edition – J2SE 58
elige dinámicamente, en tiempo de ejecución). El manejo de interfaces a través de referencia, es
similar a la referencia de una superclase, para acceder a una subclase. A continuación se muestra
un programa que ilustra el poder polimórfico de una variable de referencia de interfaz:
interface Contestadora {
void guardarMensaje (String mens);
String getMensaje ();
}
class InterfazDemo {
public static void main (String args[]) {
String mens;
Contestadora con = new Telefono();
mens = [Link]();
[Link] (“Mensaje recibido: ” + mens) ;
[Link](“cita a las 11 am”);
OBJETIVOS:
Escribir programas en Java, que manipulen los errores a través de las excepciones definidas
en el lenguaje.
Crear y utilizar en programas Java, excepciones definidas por el mismo, de acuerdo a las
necesidades de cualquier problema.
CONTENIDO:
Definición de Excepción
Tipos de excepciones
Manejo de excepciones
Jerarquía de excepciones
Propagación de excepciones
............................
61
Java ofrece una elegante solución a estos problemas con un mecanismo para el manejo de los
errores en tiempo de ejecución, conocida como manipulación de Excepciones. Una excepción es
una condición anormal que ocurre durante la ejecución de un programa e interrumpe el
flujo normal de sus instrucciones. En otras palabras, una excepción es un error en tiempo de
ejecución. Una excepción en Java es un Objeto que describe una condición excepcional, es decir,
un error que se ha producido en un fragmento de código. La gestión de excepciones de Java evita
todos los inconvenientes de la gestión de errores por validaciones y códigos de error y, en el
proceso, lleva a la gestión de errores en tiempo de ejecución al mundo orientada a objetos.
La ventaja más importante del manejo de excepciones, es que éste automatiza gran parte del
código para manejar aquellos errores en tiempo de ejecución que previamente han sido
determinados. Por ejemplo, en varios lenguajes de programación (como Visual Basic), los códigos de
errores son retornados cuando un método falla, y estos valores se deben revisar manualmente cada
vez que se invoque al método. Esta aproximación es tediosa y propensa a error. El manejo de
excepciones, controla los errores de líneas de flujo, lo que permite definir en un programa un bloque
de código, conocido como manejador de excepciones, que es ejecutado automáticamente
cuando ocurre un error. No es necesario comprobar manualmente el éxito o falla de cada operación
o método específico; si ocurre un error, éste será procesado por el manejador de excepciones.
Las excepciones pueden ser generadas por el intérprete Java o pueden ser generados por el propio
código. Las excepciones generadas por Java están relacionadas con errores fundamentales que
violan las reglas del lenguaje o las restricciones del entorno de ejecución. Las excepciones
generadas manualmente se usan para informar de alguna condición de error al método que lo
invocó.
Todos los tipos de excepciones en Java son subclases de la clase Throwable (lanzable) o de una de
sus subclases. Sólo los objetos de esta clase, o de una de sus subclases, pueden ser lanzados al
sistema en tiempo de ejecución con la cláusula throw; y sólo esta clase o una de sus subclases
puede ser un argumento en una cláusula catch. Throwable contiene una copia de la pila de
llamadas de métodos y un mensaje que describe al objeto lanzado. La clase Throwable se encuentra
en el paqueta [Link]. Las siguientes son subclases de Throwable:
- Error: los objetos de esta clase representan errores fatales en la JVM o fallas de enlace
dinámico. No es normal para un programa típico de Java lanzar Error.
Throwable
Error
ClassCircularityError InternalError
ClassFormatError OutOfMemoryError
ExceptionInitializeErr StackOverflowError
IncompatibleClassCh UnknownError
AbstractMethodError
IllegalAccessError
InstantiantionError
NoSuchFieldError
NoSuchMethodError
NoClassDefFormatErr
UnsatisfiedLinkError
VerifyError
ERROR DESCRIPCIÓN
LinkageError Se lanza cuando ocurre un error en tiempo de enlace
ThreadDeath Se lanza cuando la ejecución de un hilo falla
VirtualMachineError Se lanza con un error interno de la Máquina Virtual de Java
Throwable
Exception
ClassNotFoundException
CloneNotSupportedException
RuntimeException
AritmeticException
ArrayStoreException
IllegalArgumentException
IllegalThreadStateException
NumberFormatException
ClassCastExcepcion
IllegalMonitorStateException
IllegalStateException
IndexOutOfBoundsException
ArrayIndexOutOfBoundsExce
StringIndexOutOfBoundsExce
NegativeArraySizeException
SecurityException
NullPointerException
IllegalAccessException
InstantiationException
InterruptedException
IOException
EXCEPTION DESCRIPCIÓN
Es lanzada, cuando no se consigue un recurso o una clase
ClassNotFoundException
solicitada
CloneNotSupportedException Lanzado cuando se ejecuta el método clone() de la clase Class
RuntimeException Engloba una serie de errores en tiempo de ejecución
IllegalAccessException Engloba los errores de acceso
InstantiationException Cuando ocurre un error en la instanciación de una clase
IOException Se lanza cuando ocurre un error de Entrada/Salida (E/S)
Cuando ocurre un error, se crea un objeto que representa la excepción y se envía al sistema en
tiempo de ejecución. El sistema en tiempo de ejecución busca un manejador de excepciones
apropiado en la pila de llamadas hacia atrás, empezando con el método en el que ocurrió el error. Si
un manejador de excepción es elegido se dice que captura la excepción. Si no se encuentra un
manejador de excepción apropiado, el sistema en tiempo de ejecución y el programa Java terminan.
Ocurre un ERROR
Objeto Excepción
Objeto Excepción
entregado al sistema
creado
en tiempo de ejecución
El sistema en tiempo de
ejecución examina la pila de
llamadas empezando en el
método en que ocurrió el error
¿La Excepción
Manejador de
lanzada es del tipo
del manejador? Excepciones apropiado
Si encontrado
No
Dejar que el manejador
Buscar hacia atrás en capture la excepción
la pila de llamadas
El manejo de excepciones en Java se realiza mediante cinco palabras claves: try, catch, throw,
throws y finally. Básicamente el funcionamiento es el siguiente:
- Las sentencias del programa que pueden generar una excepción se incluyen dentro del bloque
try.
- El código puede capturar esta excepción, usando cath, y tratarla de manera racional.
- Para generar una excepción se usa throw.
- Para especificar las excepciones que puede lanzar un método se usa throws.
- Cualquier código que se tenga que ejecutar antes de que termine un método se introduce en
un bloque finally.
try {
// bloque de código
} catch (tipoExcepción e) {
// Código para manejar las excepciones para el tipoExcepción
…
} finally {
// bloque de código que se ejecutara antes de que termine el try
}
En Java, es necesario que un método capture o especifique todas las excepciones verificadas que
pueden ser lanzadas dentro del alcance del método. Esto es:
- Especificar: si un método elige no capturar una excepción debe especificar que puede
lanzarla.
- Excepciones verificadas: son excepciones que el compilador verifica que sean capturadas
o especificadas.
- Alcance del método: las excepciones pueden ser lanzadas directamente usando throw; o
indirectamente por la llamada a otros métodos.
5. JERARQUÍA DE EXCEPCIONES
Se debe capturar primero la excepción más específica, y luego proceder a capturar las excepciones
más generales hasta alcanzar aquella que sea la más genérica.
try {
FileInputStream fis = new FileInputStream(“[Link]”);
} catch (FileNotFoundException fnfe) {
…
} catch (IOException ioe) {
…
} catch (Exception e) {
…
}
6. PROPAGACIÓN DE EXCEPCIONES
En la sintaxis declarativa de los métodos, existe una sección destinada a especificar cuales son las
excepciones que dicho método no manipula en su cuerpo y que puede lanzar a la pila de llamadas.
Un método sobrescrito en una subclase solo puede lanzar excepciones declaradas en la clase padre
o hijos de las excepciones declaradas en la clase padre.
Las clases de excepción generalmente tienen constructores pero no datos ni métodos. Todo lo que
hacen es llamar a los constructores de subclase. Por eso nosotros podemos crear nuestras propias
excepciones y para ello creamos una clase que extienda de clase Exception.
/*
* Ejemplo de un programa Java con manejo de excepciones
* Sumar n números enteros
*/
OBJETIVOS:
Escribir programas en Java, que utilicen flujos de entrada y salida para interactuar con los
usuarios.
CONTENIDO:
Flujos
Tipos de flujos
Flujos predefinidos
Flujos de archivo
Serialización de objetos
............................
69
1. FLUJOS (STREAMS)
Los programas Java realizan procesos de E/S a través de flujos. El programa establece una conexión
con un dispositivo físico para leer información de él o para escribir información en él, y la
información se lee o escribe en forma serial.
Un flujo puede ser definido como una entidad lógica que produce o consume información, y
está encadenado a un dispositivo físico por el sistema de E/S de Java. Los flujos pueden
ser dirigidos a cualquier dispositivo de E/S compatible. Todos los flujos se comportan de la misma
manera, aunque los dispositivos físicos reales a los que estén ligados difieran. Así las mismas clases
y métodos de E/S pueden ser aplicadas a cualquier tipo de dispositivo, bien sea bien sea la entrada
o salida estándar, la memoria, un archivo, una conexión de red, etc.
2. TIPOS DE FLUJOS
El paquete [Link] tiene las clases necesarias para la utilización de flujos en Java. Los flujos pueden
ser clasificados de la siguiente manera:
- De acuerdo con el uso que se les dé: se pueden clasificar en flujos consumidores
(obtienen datos de una fuente) y flujos de procesamiento (utilizan funciones para la
conversión, clasificación y filtrado de datos obtenidos de los flujos).
Flujos
De Caracteres De Bytes
BufferedReader BufferedWriter
LineNumberReader CharArrayWriter
CharArrayReader
OutputStreamWrit
er
InputStreamReader
FileWriter
FileReader
FilterWriter
FilterReader
PipedWriter
PushBackReader
StringWriter
PipedReader
StringReader PrintWriter
InputStream OutputStream
FileInputStream
FileOutputStream
PipedInputStream
PipedOutputStream
ByteArrayInputStream
FilterOutputStream
StringBuferInputStream
SequenceInputStream DataOutputStream
FilterInputStream PrintStream
DataInputStream
BufferedOutputStre
am
LineNumberInputStrea
PushBackOuputStre
BufferedInputStream am
ObjectOutputStream
PushBackInputStream
ObjectInputStream ByteArayOuputStream
De las jerarquías de clases de flujos en Java, es importante señalar que las clases que aparecen
sombreadas representan las clases procesadoras (añaden características a la forma de recibir o
enviar los datos de los dispositivos) y las otras son las clases consumidoras (definen de dónde o a
dónde se están enviando o recibiendo los datos, es decir al dispositivo que se conecta en flujo).
La siguiente tabla explica la jerarquía de clases para los flujos de carácter:
COMPONENTE PROPÓSITO
InputStream y OutputStream Son clases abstractas que permiten leer bytes de datos.
3. FLUJOS PREDEFINIDOS
En el paquete [Link] se encuentra la clase System que encapsula algunos aspectos del entorno
de ejecución. Esta clase tiene 3 variables de clase públicas que están asociadas con flujos:
- out: se refiere al flujo de salida estándar que, por omisión, es la consola ([Link])
- in: se refiere a la entrada estándar que, por omisión, es el teclado ([Link])
- err: se refiere al error estándar que, por omisión, también es la consola ([Link])
En Java, la entrada por consola se efectúa leyendo bytes de un flujo de entrada. Estos bytes se
pueden leer en varios objetos, como pueden ser caracteres y cadenas. El método de entrada de mas
bajo nivel es read(). Este método está definido en la clase InputStream. Cada vez que se llama al
método read() lee un único byte del flujo de entrada y lo devuelve como un valor entero.
El método devuelve -1 cuando encuentra el final del flujo.
El siguiente programa muestra el funcionamiento del método read(), donde leen caracteres de la
entrada estándar hasta que el usuario pulsa la letra “s”.
import [Link].*;
public class LecturaPorConsolaCaracter {
public static void main (String args[]) throws IOException {
char caract;
[Link](“Introduzca caracteres, ‘s’ para salir: ”);
do {
caract = (char) [Link]( );
[Link] (caract);
} while (caract != ‘s’);
}
}
[Link] es, por omisión, un flujo con búfer, es decir, no se pasa ninguna entrada al programa
hasta que se pulsa la tecla ENTER. Esto hace que el método read() no sea muy útil para entradas
por consola interactivas, ya que una de las acciones de entrada más comunes que realiza un
programa es la lectura de una cadena completa del teclado y el método read() solo permite leer
carácter por carácter. Para facilitar la lectura por consola de una cadena entera con una sola
instrucción se utiliza el método readLine() de la clase BufferedReader. Este método lee todos los
caracteres hasta encontrar “\n” o “\r” y devuelve un String (sin incluir estos caracteres).
El siguiente programa muestra el funcionamiento del método readLine(), donde lee una cadena de
caracteres de la entrada estándar.
import [Link].*;
public class LecturaPorConsolaCadena {
public static void main (String args[]) throws IOException {
String str;
BufferedReader br = new BufferedReader (new InputStreamReader([Link]));
[Link] (“Escriba una cadena de caracteres sin espacio y presione ENTER.”);
s = [Link] ();
[Link] (“Ud. escribió: ” + str);
}
}
El siguiente programa utiliza el método write() para imprimir el carácter “A” seguido de un carácter
de línea nueva.
5. FLUJOS DE ARCHIVOS
Para utilizar los archivos en Java, se pueden emplear tanto los flujos de carácter como los flujos de
byte y ambos funcionan de manera similar, sólo varían en la forma como el lenguaje se comunica
con el dispositivo físico internamente. Para comprender esto, hay que tener en cuenta que los
archivos para Java solo son secuencias de bytes, denominados archivos secuenciales; razón por
la cual no hace diferencia si el archivo es de texto o es un archivo estructurado. Por otro lado
también existen los archivos de acceso aleatorio que son tratados de forma diferente.
Las clases FileReader y FileWriter crean flujos de caracteres asociados a los archivos
secuenciales. Mientras que las las clases FileInputStream y FileOutputStream crean flujos de
bytes asociados a los archivos. Para abrir un archivo, simplemente es necesario crear un objeto de
estas clases, especificando el nombre del archivo en el constructor. Para cerrar el archivo, se invoca
al método close(), definido en todas las clases.
o FileReader(String rutaArchivo) throws FileNotFoundException // Abrir para Lectura
o FileInputStream(String rutaArchivo) throws FileNotFoundException // Abrir para Lectura
o FileWriter(String rutaArchivo) throws IOException // Abrir para escritura
o FileOutputStream(String rutaArchivo) throws IOException // Abrir para Escritura
El paquete [Link] declara una clase RandomAccessFile, que sirve para leer o escribir en archivos
de forma aleatoria. Los argumentos de la clase instanciada deciden si el objeto será utilizado para
leer o escribir. Para abrir un archivo, simplemente es necesario crear un objeto de ésta clases,
especificando el nombre del archivo en el constructor y el modo de apertura.
- RandomAccessFile(String rutaArchivo, “r”) // Abrir para Lectura
- RandomAccessFile(String rutaArchivo, “rw”) // Abrir para Lecto-Escritura
- void seek(long pos): Posiciona el puntero de archivo antes del byte especificado.
En caso de que el fin de archivo se alcance antes de leer el número de bytes especificado, entonces
se lanza una EOFExcepcion y en caso de no leer o escribir un byte, entonces se lanza una
IOExcepcion.
Para escribir una clase cuyos objetos sean serializables en Java, la clase tiene que implementar la
interfaz [Link]. Serializable es una interfaz sin métodos que permite identificar la
semántica de la serialización.
interface Serializable {
}
La clase del objeto, la firma de la clase y los valores de los campos no transient y no static de un
objeto se escriben mediante el mecanismo de serialización por omisión. Cualquier referencia a otros
objetos en campos no transient y no static causara que los objetos referenciados se escriban.
import [Link].*;
public class Serializar {
public static void main(String args[]) {
FileOutputStream fos = new FileOutputStream(“c:\[Link]”);
ObjectOutputStream oos = new ObjectOutputStream(fos);
[Link](1243); // Escribe un objeto de Integer
[Link](“Ejemplo”); // Escribe cualquier tipo Object
[Link](); [Link]();
}
}
El siguiente programa muestra como son recuperados (deserialización) los objetos escritos en el
archivo [Link]:
import [Link].*;
public class Deserializar {
public static void main(String args[]) {
FileInputStream fis = new FileInputStream(“c:\[Link]”);
ObjectInputStream ois = new ObjectInputStream(fis);
[Link]([Link]);
[Link]((String)[Link]());
[Link](); [Link]();
}
}
OBJETIVOS:
Escribir programas en Java que sean capaces de interactuar con una base de datos.
CONTENIDO:
La API JDBC
............................
80
Curso de Java Standard Edition – J2SE 80
Hasta los momentos hemos visto como hace Java para crear objetos, para implementar el principio
de Herencia, el concepto de clases abstractas e interfaces. Aprendimos sobre paquetes y sobre el
manejo de excepciones. Además, entendimos el simple pero poderoso mecanismo para manejar las
entradas y salidas. En este tema, veremos como la información guardada en una base de datos
puede ser recuperada a través de un programa en Java, y aprenderá a escribir información en una
base de datos desde un programa hecho en Java.
Ya que no se puede definir un denominador común para el almacenamiento y acceso de datos entre
los tipos de bases de datos, la especificación JDBC autoriza requerimientos no específicos en el
DBMS (Data Base Management System) subyacente. En lugar de colocar requerimientos de cómo
se debe implementar el DBMS para poderlo usar (ODBC), la especificación JDBC de Java, coloca
todos sus requerimientos en la implementación específica del mismo.
Al escribir programas en Java que se comuniquen con una base de datos, se requiere:
Cuando hablamos de acceso a una base de datos, las siguientes operaciones son las más
importantes a través de un programa Java: el programa debe ser capaz de leer desde una base de
datos y el programa debe ser capaz de escribir información a una base de datos.
En Java, hay una serie de pasos para acceder la información que se encuentra en una base de datos
y estos son:
Escribir programas en Java que se conecten con una base de datos y trabajen, es tan simple como
implementar estos cuatro pasos.
El API de JDBC proporciona una forma universal para acceder a datos desde el lenguaje de
programación de Java. Usando el API JDBC, usted puede acceder virtualmente cualquier fuente de
datos, desde las bases de datos relacional a las hojas de cálculo y archivos planos. La tecnología de
JDBC también proporciona una base común sobre la cual pueden construirse herramientas e
interfaces.
Para trabajar con las empresas líderes en el campo de las bases de datos, Sun Microsystems,
desarrolló una sencilla API para acceso a bases de datos JDBC. En el proceso de desarrollo, se
establecieron tres puntos principales:
JDBC es un API que soporta SQL, debido a que permite construir sentencias SQL embebidas
dentro de las llamadas a la API JDBC de Java. JDBC permite comunicar sin problemas el mundo de
los manejadores de bases de datos con el de la programación Java, ya que se construyó en base las
experiencias anteriores en el manejo de bases de datos, como por ejemplo el uso de la tecnología
ODBC de Microsoft. Y finalmente, el trabajar con JDBC se hace sencillo, porque consiste
básicamente en hacer uso de funciones predefinidas y que se comportan igual para cualquier
manejador de base de datos.
JDBC logra establecer, para las interfaces Java, implementaciones diferentes para cada manejador.
El grupo de clases, que implementan las interfaces JDBC para un motor de base de datos particular
es llamado un Driver JDBC. En la elaboración de una aplicación de bases de datos, no interesa
conocer como están implementadas estas clases, ya que JDBC oculta la implementación específica
para cada base de datos, y solo se deben emplear los métodos definidos en las diferentes interfaces
JDBC.
La arquitectura JDBC, establece que “una aplicación Java trabaja con cualquier bases de
datos, empleando los métodos definidos en las interfaces JDBC las cuales son
específicas para cada manejador”.
La figura anterior, muestra como una aplicación usa JDBC para comunicarse con una o más bases
de datos sin conocer los detalles concernientes a la implementación de “Driver” específico para dicha
base de datos.
En esta API, existen clases e interfaces básicas que se encuentran en cualquier programación de
base de datos que involucre JDBC y estas son:
<<Interfaz>>
DriverManager Registers
Driver
0..n
Provides
0..n
<<Interfaz>> <<Interfaz>> Retirves <<Interfaz>>
Connection Statement ResultSet
1 Creates 0..n 1 0..n
Provides
Provides
<<Interfaz>>
CallableStatement
Todas las clases con acceso a Base de Datos en la API JDBC, lanzan SQLException, la cual
necesita ser capturada y manejada.
Como hemos visto, en el trabajo con bases de datos en Java existen cuatro pasos básicos: cargar el
controlador, realizar la conexión, realizar las peticiones sobre la base de datos y por último se debe
cerrar la conexión. Ahora, veremos como hacer cada una de estas tareas.
Los fabricantes de sistemas de bases de datos proveen sus propios controladores para poder
conectarse con la base de datos. Para cargar el controlador, necesitamos usar el método forName
especificado en la clase Class con el nombre del controlador como argumento. Los objetos de la
clase Class son construidos automáticamente por la JVM cuando se cargan las clases. Para cargar un
controlador de base de datos, incluimos la siguiente sentencia antes de hacer cualquier acceso a la
base de datos.
El nombre del controlador es específico a cada base de datos. Veamos como cargar el controlador
para diversos manejadores de bases de datos:
Las aplicaciones usan la clase DriverManager para establecer la conexión con el DBMS. La clase
DriverManager es responsable de buscar o rastrear las diferentes implementaciones JDBC que
pueden existir en un sistema. La aplicación requiere que DriverManager le dé una conexión de base
de datos.
La clase DriverManager provee un método llamado getConnection(), el cual tiene tres argumentos:
- Un URL de base de datos.
- Identificación del usuario.
- Clave de usuario.
protocol:<subprotocol>:<subname>
jdbc:odbc:Sample
donde,
- jdbc, es el protocol
- odbc, es el subprotocol
- Sample, es el subname
Microsoft Access
[Link](“[Link]”);
Connection conn;
String databaseURL = “jdbc:odbc:Sample”;
conn = [Link](databaseURL,””,””);
MySQL Server
[Link](“[Link]”);
Connection conn;
String databaseURL = "jdbc:mysql://localhost:3306/test”;
String user = “root”;
String password = “sql”;
conn = [Link](databaseURL,user,password);
Un objeto Connection es una simple sesión de base de datos. Podemos tener cualquier número de
objetos Connection en un programa.
Habiendo establecido una conexión a base de datos, usando el método getConnecticon() de la clase
DriverManager, se está en posición de ejecutar peticiones sobre esa base de datos. Dichas
peticiones, se refieren a ejecutar sentencias SQL sobre la base de datos, bien sean sentencias:
Para ejecutar las sentencias SQL mencionadas anteriormente es necesario hacer uso de objetos
Statement, PreparedStatement y ResultSet.
- Objetos Statement: La interfaz Statement provee métodos para hacer llamadas a las
sentencias SQL. En este caso, es indiferente a que DBMS esté conectado los métodos
funcionan igual para todos, ya que una simple interfaz es provista por el JDBC para acceder a
la información de cualquier base de datos.
Para ejecutar sentencias SQL, primero se declara un objeto Satatement y a través del
objeto Connection creamos una sentencia usando el método createStatement().
[Link](“[Link]”);
Connection conn;
String databaseURL = “jdbc:odbc:Sample”;
conn = [Link](databaseURL,”user1”,”xyz”);
Statement sentencia = null;
int filas = 0;
sentencia = [Link]();
nro= [Link](“INSERT INTO Tab VALUES(‘Enero’,10)”);
Podemos ver que, en la sentencia SQL se han empleado variables en lugar de constantes
como valores; de igual forma, también se pueden colocar expresiones dentro de una
sentencia que va a ser ejecutada por un objeto Statement.
El API JDBC de Java, permite crear una sentencia SQL una sola vez y aplicarla cada que
queramos ejecutarla. La clase PreparedStatement, permite construir las sentencias SQL
requeridas una vez y ejecutarlas cualquier número de veces en la aplicación. Un
PreparedStatement es una llamada a una base de datos precompilada que requiere que los
parámetros sean definidos.
Para ejecutar sentencias SQL usando el objeto Statement cada vez, damos el nombre de la
columna y los valores. Cuando usamos el objeto PreparedStatement no podemos especificar
los valores cuando se crea el objeto, ya que en el momento de construcción de la sentencia
los valores no serán conocidos. Sólo proveemos los poseedores de lugares usando el símbolo
? y después se substituirá cada símbolo con el valor deseado.
[Link](“[Link]”);
Connection conn;
String databaseURL = “jdbc:odbc:Sample”;
conn = [Link](databaseURL,”user1”,”xyz”);
Statement sentencia = null;
ResultSet resultados = null;
sentencia = [Link]();
resultados = [Link](“SELECT mes, dia FROM Tab”);
Como el método executeQuery(), puede devolver varias filas, puede ser necesario
desplazarnos dentro de ese conjunto de filas. Para ello, emplearemos el método next()
provisto en la clase ResultSet. Este método nos permite iterar a través del ResultSet. Dicho
método retorna true, si existe un registro activo o false en caso contrario. Ees de hacer
notar que para obtener la primera fila del ResultSet, es necesario emplear el método next()
ya que el mismo no está posicionado en ningún registro cuando se obtienen los datos.
while([Link]())
[Link](“\n Deslazándose en el cursor…”);
[Link](“\n No hay más datos en el cursor…”);
En el uso anterior del objeto ResultSet no se ha recuperado ninguna información de las filas
resultado, solo nos desplazamos por ellas. Para recuperar la información de las filas, se
utilizan los métodos getXXX() de la clase ResultSet. Cada campo de información disponible
en una fila es de algún tipo de dato. Necesitaremos hacer una correspondencia entre los
tipos de datos del DBMS con los métodos getXXX(). Hay un número de métodos getXXX
disponibles en la clase ResultSet, algunos de los más comunes son:
while([Link]()) {
[Link]([Link](1));
[Link]([Link](“dia”));
[Link]([Link](“mes”));
[Link]([Link](2));
}
- Soporte de Cursores: El API JDBC provee soporte limitado de cursores (ResultSet). Permite
que una aplicación obtenga un cursor asociado con el resultado de un Query a través del
método executeQuery(); pero el movimiento del cursor ocurre, por omisión, sólo con
dirección hacia delante. Por lo que, es necesario activar la navegabilidad del cursor.
Para que un ResultSet sea scrollable (navegable), hay que pasarle dos argumentos, bien
sea al createStatement() o al método prepareStatement(). Los argumentos a pasar son:
MÉTODO DESCRIPCIÓN
TIPO SIGNIFICADO
Una vez que el objeto ResultSet se hace “scrollable”, entonces el cursor se puede mover y
apunta a filas específicas, donde se puede actualizar, borrar, etc. Algunos de los métodos
disponibles en ResultSet para el movimiento del cursor se listan a continuación:
La información de las filas de un ResultSet, pueden ser actualizadas utilizando los métodos
updateXXX() de la clase ResultSet., donde XXX corresponde a un tipo de dato presente el
DBMS. Algunos de los métodos updateXXX más comunes son:
Todos son métodos que trabajan sobre la fila actual. Estos métodos están sobrecargados y
aceptan un entero o una cadena como argumento para representar la columna. Si el
argumento es entero, indica el número de la columna en la sentencia, pero si el argumento
es cadena, representa el nombre de la columna dada en la tabla.
[Link](1,”Marzo”);
[Link](“dia”,18);
[Link](“mes”,”Abril”);
[Link](2,19);
Como hemos visto la conexión a la base de datos se hace a través de la clase DriverManager, la cual
le da a la aplicación un objeto Connection que representa la conexión. De ese objeto Connection, se
pueden obtener muchos objetos Statement y ResultSet para manipular la información de la base de
datos.
Al terminar de trabajar con una base de datos, es buena práctica de programación cerrar los objetos
Connection, Statement y ResultSet que se tengan asociados a la misma, para de esta manera liberar
Existen otras clases e interfaces de soporte provistas por JDBC para ayudar a la funcionalidad del
API JDBC. Todas estas clases se definen en el paquete [Link].
5.1. SQLEXCEPTION
Extiende de la clase [Link], esta clase provee más información relacionada a errores
de la base de datos. Usamos esta clase ampliamente en todos los programas Java que utilicen JDBC.
Esta clase incluye información acerca de:
Esta excepción debe ser obligatoriamente capturada y manejada por todo programa que emplee las
funcionalidades de la API JDBC de Java.
Todas estas clases heredan de la clase [Link]. Ellas extienden para proveer niveles de
granularidad a la información ya existente en la clase Date. Son necesarias para proveer
compatibilidad con los campos tipo fecha de los manejadores de bases de datos.
5.3. TYPES
La clase [Link], define constantes para identificar tipos genéricos SQL, llamados tipos
JDBC. Esta es una clase abstracta. LA misma no añade funcionalidades a los métodos ya definidos
en la clase Object. Algunas variables de clase, que esta clase contiene son:
- ARRAY
- BIT
- BINARY
- CHAR
- CLOB
- DATE
- INTEGER
- NUMERIC
- REAL
- VARCHAR
El siguiente es un programa que ilustra como es el proceso de acceso a Bases de Datos utilizando la
API JDBC. Este programa se conecta con una base de datos en MySQL.
/**
* Programa Base de Datos
* @date: 26/09/2005
* @author: Ronel J. Rivas R.
*/
package database;
import [Link].*;
import [Link].*;
public JExampleDB() {
super();
}
public void cerrarConexion() throws SQLException {
[Link]();
}
public void consultarTabla() throws SQLException {
// Crear la sentencia SQL
stmt = [Link]();
String SQL = "SELECT * FROM Ejemplo";
res = [Link](SQL);
// Mostrar el resultado por pantalla
while ([Link]()) {
[Link]([Link](1)+" - ");
[Link]([Link]("mes"));
}
// Liberar los recursos
[Link](); [Link]();
}
public void crearConexion(String URL, String user, String passw) throws SQLException {
conn = [Link](URL, user, passw);
}
} catch (ClassNotFoundException e) {
[Link]("ERROR: No se encuentra el Driver para el DBMS...");
} catch (SQLException e) {
[Link]("ERROR: No se pudo ejecutar la sentencia...");
}
}
}
OBJETIVOS:
Escribir programas Java que presenten GUI (Interfaces Gráficas de Usuario), empleando la
tecnología SWING.
CONTENIDO:
Administradores de diseño
Manejo de eventos
............................
95
Curso de Java Standard Edition – J2SE 95
El objetivo de este tema es introducir los aspectos básicos de diseño y construcción de una interfaz
gráfica de usuario (GUI – Graphical User Interface) y presentar cómo se proporciona el
funcionamiento de dicha interfaz. Con este propósito se presenta el modelo de objetos de los
componentes gráficos y la programación basada o dirigida por eventos.
Hasta el momento las aplicaciones creadas sólo han presentado y leído información textual para
realizar la interacción con el usuario (aplicaciones de consola o en modo texto). El lenguaje de
programación Java proporciona distintos paquetes con bibliotecas de clases que implementan los
elementos gráficos y posibilitan la creación de interfaces gráficas de una forma sencilla. Este
conjunto de paquetes se denomina Java Foundation Classes (JFC). La JFC o Clases
Fundamentales de Java, proporcionan una rica colección de clases de interfaz de usuario.
Las JFC son un grupo de APIs usadas para desarrollar la interfaz gráfica de usuario y estas son:
o Abstract Windows Toolkit (AWT): es el principal conjunto de herramientas usado por
Java para crear interfaces de usuario. Proporciona la base sobre la que descansa el resto de
la construcción del JFC. El propósito principal de AWT es soportar ventanas de Applet.
o API 2D: proporciona gráficos de 2 dimensiones mejorados, texto y capacidades de
imágenes para programas Java, a través de extensiones a AWT. Este amplio paquete de
presentación soporta arte de líneas, texto e imágenes, para desarrollar interfaces de usuario
ricas, programas de dibujo y editores de imágenes.
o Swing: es el conjunto de componentes más ligeros construidos sobre AWT. Swing
proporciona reemplazos ligeros para los componentes pesados de AWT, en adición de una
multitud de componentes adicionales de los que carece AWT. Swing también dispone de
una infraestructura notable para implementar interfaces gráficas de usuario como los
componentes de aspecto (Look and Feel) de diferentes plataformas.
o Accesibilidad: el JFC contiene numerosas herramientas de accesibilidad, que trabajan
junto con el API de accesibilidad.
Es de hacer notar, que en el curso se estudiaran sólo los componentes Swing y sus
componentes gráficos más frecuentes, así como breves ejemplos de su uso.
Los pasos básicos para la creación de una interfaz gráfica de usuario son los siguientes:
o El diseño y composición de la apariencia de la interfaz gráfica de la aplicación.
Esto implica la elección de una ventana principal (contenedor) en la que se van a incluir el
resto de los elementos gráficos de interacción (componentes). El diseño se completa con la
elección del resto de los componentes gráficos (botones, etiquetas, menús, etc.) que se
añaden a la ventana principal, su disposición y la forma en que van a interactuar.
o Creación de componentes. Significa escribir el código que crea los componentes y la
apariencia de la interfaz.
o Manejo de eventos. Esto es escribir el código que proporciona el comportamiento de
dicha interfaz como respuesta a las interacciones de los usuarios. Cada una de las acciones
del usuario sobre la interfaz (Ejemplo: hacer clic sobre un botón), se traduce en la creación
de un evento en Java. Por tanto hay que proporcionar los manejadores de eventos para
responder a las interacciones de los usuarios.
o Visualización. Una vez visualizada la interfaz, la aplicación queda a espera de las
interacciones del usuario que provocarán la ejecución de los manejadores de eventos.
Cómo se ha visto en los temas anteriores, en Java prácticamente todas las cosas son objetos.
Esta circunstancia sigue siendo válida en la creación de interfaces gráficas. Las ventanas son
objetos, todos los componentes gráficos de interacción contenidos en una ventana son objetos y
como resultado de las acciones del usuario se generan eventos que también son objetos. En
Java una interfaz gráfica se construye componiendo distintos objetos que
implementan elementos gráficos de interacción (botones, campos de texto, etiquetas,
etc.).
Finalmente, en Java las interfaces gráficas están compuestas básicamente por tres elementos:
Swing, en comparación con las otras tecnologías para la creación de interfaces gráficas, presenta
diversas ventajas y funcionalidades, entre las que cabe destacar las siguientes:
o Los componentes Swing son JavaBeans. Los componentes son unidades autocontenidas
y reusables. Los componentes pueden ser manipulados visualmente usando herramientas de
construcción para aplicaciones visuales. La tecnología de componentes se incorporan a la
plataforma Java a través del concepto de JavaBean. Las características que distinguen a un
JavaBean de una simple clase Java son: Introspección (todas sus variables son privadas),
persistencia (permiten guardar y restaurar su estado - Serialización), personalización (se
configuran visualmente) y manejo de eventos (utilizan los eventos para comunicarse con otros
objetos). Esto permite que los componentes Swing sean fácilmente integrados en
herramientas de diseño de componentes.
CAMBIO
Evento
COMPONENTE
VISTA ACTUALIZACIÓN
MODELO
(Clases Entidad)
CONTROLADOR
(Listener) ACTUALIZACIÓN
CAMBIO
Por ejemplo, como los modelos gestionan y almacenan los datos existe la posibilidad de
compartir un mismo modelo entre varios componentes. Cada uno de los componentes puede
modificar el modelo y dicha modificación se reflejará de forma automática en el resto de los
componentes que comparten dicho modelo.
CAMBIO CAMBIO
CAMBIO CAMBIO
o Accesibilidad. Todos los componentes Swing son compatibles con los dispositivos de ayuda
para personas discapacitadas y permiten utilizar interfaces alternativas, tales como braille y
sintetizadores de voz.
Como Swing presenta una gran cantidad de clases gráficas no es posible ni presentarlas todas ni
describirlas de forma completa. Se trabajará con las clases más utilizadas, estructuradas por
grupos, y sus métodos más importantes. Las clases gráficas se presentan estructuradas en los
siguientes grandes grupos: clases básicas, contendores (contenedores de alto nivel e
intermedios) y componentes atómicos.
o CLASES BÁSICAS: proporcionan el soporte y las funcionalidades básicas para el resto de los
componentes. La raíz de todos los elementos gráficos en Java es la clase abstracta
[Link] y su subclase [Link]. La clase
[Link], es la clase base para prácticamente todos los componentes
Swing. A continuación se describen las clase básicas:
MÉTODO FUNCIONALIDAD
void paint(gGraphics)
void repaint() Dibujo y actualización del componente en la pantalla.
void update(Graphics)
boolean isVisible()
Comprueba o establece si el componente es visible
void setVisible(true)
boolean isEnabled() Permite conocer si un componente está activado y
void setEnabled() activarlo o desactivarlo
Point getLocation()
Point getLocationOnScreen() Devuelve o establece la posición del componente
void setLocation(Point) respecto al componente padre o respecto a la pantalla
void setLocation(int, int)
Dimension getSize()
void setSize(int, int)
Obtiene o establece el tamaño de un componente, en
void setSize(Dimension)
píxeles o como un objeto Dimension
int getWidth()
int getHeight()
Obtiene la alineación del componente. Las constantes
float getAligmentX() correspondientes son:
float getAligmentY() CENTER_ALIGMENT, LEFT_ALIGMENT, RIGHT_ALIGMENT,
TOP_ALIGMENT Y BOTTOM_ALIGMENT
Color getForeground()
Color getBackground() Obtiene o establece el color de fondo o de primer
void setForeground(Color) plano del componente
void setBackground(Color)
Container getParent() Obtiene el contenedor padre del componente
String getName() Obtiene o establece el nombre del componente según
void setName(String) la cadena proporcionada
MÉTODO FUNCIONALIDAD
void add(Component) Añade un componente en el contenedor, por omisión
void add(Component, int) al final de la lista salvo que se indique un índice.
Component getComponentAt(int,int) Obtiene el componente que contiene un determinado
Component getComponentAt(Point) punto (x,y)
Component [] getComponents() Obtiene todos los componentes del contenedor
void remove(Component) Elimina un componente, dado su identificador o por
void remove(int) su posición en la lista de componentes (o para el
void removeAll() primer componente), o todos los componentes.
void setLayout(LayoutManager) Establece u obtiene el administrador de diseño que
LayoutManager getLayout() utiliza el contenedor.
MÉTODO FUNCIONALIDAD
void setBorder(Border) Establece u obtiene el borde que muestra un
Border getBorder() componente alrededor de sus límites.
Establece si un componente es opaco o no
void setOpaque(boolean)
(transparente).
Establece el texto a mostrar como pista o ayuda
contextual del componente que se muestra en una
void setToolTipText(String)
ventana emergente cuando el ratón se detiene sobre
un objeto particular de la pantalla.
[Link]
[Link]
[Link] [Link]
MÉTODO FUNCIONALIDAD
Ajusta el tamaño de la ventana según el tamaño
void pack()
preferido y disposición de sus componentes.
void toFront()
Coloca la ventana delante o detrás de otras ventanas.
void toBack()
Destruye la ventana así como sus componentes y
void dispose()
libera los recursos asignados a ella.
boolean isShowing() Obtiene si la ventana es visible.
void show() Hace que la ventana sea visible.
MÉTODO FUNCIONALIDAD
JFrame() Constructores que crean una ventana, inicialmente oculta y a
JFrame(String) la que se le puede asignar un título.
String getTitle()
Obtiene o establece el titulo de la ventana.
void setTitle(String)
void setResizable(boolean)
Establece o determina si la ventana puede cambiar de tamaño.
booleann isResizable()
JRootPane createRootPane()
Crea, obtiene o establece el panel raíz de la ventana. Este
JRootPane getRootPane()
panel gestiona el panel de contenido y la barra de menús.
void setRootPane(JRootPane)
Container getContentPane() Obtiene o establece el panel de contenido de la ventana.
void setContentPane(Container) Contiene a todos los componentes gráficos de la ventana.
JMenuBar getMenuBar()
Obtiene o establece la barra de menús de la ventana.
void setMenuBar(JMenuBar)
Obtiene o establece el comportamiento de la ventana cuando
int getDefaultCloseOperation() el usuario trata de cerrarla. El parámetro debe ser una de las
void setDefaultCloseOperation(int) constantes:JFrame.DO_NOTHING_ON_CLOSE,
JFrame.HIDE_ON_CLOSE ó JFrame.DISPOSE_ON_CLOSE.
package interfacesGraficas;
import [Link].*;
MÉTODO FUNCIONALIDAD
JDialog(JFrame) Constructores en los que se indica la ventana
JDialog(JFrame, boolean) principal (JFrame), si es modal o no y el titulo.
JDialog(JFrame, String) Existen los mismos constructores en donde la
JDialog(JFrame, boolean, String) ventana principal es un JDialog.
import [Link].*;
JOptionPane JFileChooser
MÉTODO FUNCIONALIDAD
static int showMessageDialog(Component, Object) Muestra un cuadro de diálogo modal que
presenta información al usuario y tiene un
static int showMessageDialog(Component, Object,
botón “Aceptar”. Los argumentos especifican
String, int)
el componente padre, el mensaje, el título, el
static int showMessageDialog(Component, Object, tipo de mensaje y el icono del cuadro de
String, int, Icon) diálogo.
static int showConfirmDialog(Component, Object)
static int showConfirmDialog (Component, Object, Muestra un cuadro de diálogo modal que
String, int) realiza una pregunta al usuario. Los
static int showConfirmDialog (Component, Object, argumentos especifican el componente padre,
String, int, int) el mensaje, el título, el tipo de opción, el tipo
static int showConfirmDialog (Component, Object, de mensaje y el icono del cuadro de diálogo.
String, int, int, Icon)
static int showInputDialog(Object)
static int showInputDialog(Component, Object) Muestra un cuadro de diálogo modal en el
que solicita una entrada al usuario. Los
static int showInputDialog (Component, Object, argumentos especifican el componente padre,
String, int) el mensaje, el título, el tipo de mensaje y el
static int showInputDialog (Component, Object, icono del cuadro de diálogo.
String, int, Icon)
Muestra un cuadro de diálogo modal
personalizado. Los argumentos especifican el
static int showOptionDialog (Component, Object, componente padre, el mensaje, el título, el
String, int, int, Icon, Object[],Object) tipo de opción, el tipo de mensaje, el icono,
las opciones y la opción predeterminada del
cuadro de diálogo.
- JOptionPane.ERROR_MESSAGE - JOptionPane.PLAIN_MESSAGE
- JOptionPane.INFORMATION_MESSAGE - JOptionPane.WARNING_MESSAGE
- JOptionPane.QUESTION_MESSAGE
- JOptionPane.DEFAULT_OPTION - JOptionPane.OK_CANCEL_OPTION
- JOptionPane.YES_NO_OPTION - JOptionPane.YES_NO_CANCEL_OPTION
- JOptionPane.YES_OPTION - JOptionPane.OK_OPTION
- JOptionPane.NO_OPTION - JOptionPane.CLOSED_OPTION
- JOptionPane.CANCEL_OPTION
// Mensaje de confirmación
int opc = [Link](this,
“¿Desea Agregar el Registro?, // Mensaje
“Mensaje de confirmación”, // Titulo
JOptionPane.YES_NO_OPTION); // Tipo Opciones
Gráfico 8. Cuadro de dialogo de Confirmación
// Cuadro de opción personalizado
Object[] textoOpciones = {“Sí adelante”,”Ahora no”, “No sé que hacer”};
int op = [Link](this,
“¿Desea realizar la operación ahora?”, // Mensaje
“Mensaje de Confirmación”, // Titulo
JOptionPane.YES_NO_CANCEL_OPTION, // Tipo opciones
JOptionPane.QUESTION_MESSAGE, // Tipo de Mensaje
null, // Icono
Gráfico 9. Cuadro de dialogo Personalizado
textoOpciones, // Opciones
textoOpciones[0]); // Opción principal
}
public static void main(String[] args) {
EjemploJOptionPane ventana = new EjemploJOptionPane ();
[Link](true);
}
}
MÉTODO FUNCIONALIDAD
JFileChooser() Constructores. Mediante los argumentos se
JFileChooser(String) establece el directorio actual
Muestra el selector de archivos abrir o guardar.
int showOpenDialog(Component) Devuelven como resultado si el usuario ha
int showSaveDialog(Component) aceptado o no la operación (APPROVE_OPTION ó
CANCEL_OPTION).
void setSelectedFile(File) Establece u obtiene el archivo o directorio
File getSelectedFile() seleccionado
Estable u obtiene el mo de selección. Por omisión
void setFileSelectionMode(int) sólo se pueden seleccionar archivos (FILES_ONLY),
int getFileSelectionMode() pero se puede cambiar a solo directorio
(DIRECTORIES_ONLY) o ambos (FILES_AND_DIRECTORIES)
boolean getControlButtonsAreShown() Obtiene o establece si se muestran o no los
void setControlButtonAreShown(boolean) botones de control predeterminados del selector
package interfacesGraficas;
import [Link].*;
import [Link].*;
JComponent
MÉTODO FUNCIONALIDAD
JPanel() Constructores. Permite crear un panel para agrupar
componentes, además permite establecer el
JPanel(LayoutManager) administrador de diseño para el contenedor.
void add(JComponent)
MÉTODO FUNCIONALIDAD
JScrollPane() Constructores. Se puede indicar el componente que
JScrollPane(Component) proporciona el contenido y la política de
JScrollPane(Component, int, int) presentación de las barras de desplazamiento.
Establece el componente que proporciona el
void setViewportView(Component)
contenido.
Establece u obtiene la política de presentación de la
barra de desplazamiento vertical. Las posibilidades
void setVerticalScrollBarPolicy(int) son: que se muestre cuando sea necesario
int getVerticalScrollBarPolicy() (VERTICAL_SCROLLBAR_AS_NEEDED), que se muestren
siempre (VERTICAL_SCROLLBAR_ALWAYS) y que no se
muestren nunca (VERTICAL_SCROLLBAR_NEVER).
Establece u obtiene la política de presentación de la
barra de desplazamiento horizontal. Las
void setHorizontalScrollBarPolicy(int) posibilidades son: que se muestre cuando sea
necesario (HORIZONTAL_SCROLLBAR_AS_NEEDED), que se
int getHorizontalScrollBarPolicy() muestren siempre (HORIZONTAL_SCROLLBAR_ALWAYS) y
que no se muestren nunca
(HORIZONTAL_SCROLLBAR_NEVER).
package interfacesGraficas;
import [Link].*;
import [Link].*;
MÉTODO FUNCIONALIDAD
JSplitPane()
Constructores. Se le puede proporcionar la
JSplitPane(int)
orientación y los componentes de sus dos partes.
JSplitPane(int, Component, Component)
Establece u obtiene la orientación de la división. Por
void setOrientation(int) omisión aparece uno al lado del otro
int getOrientation() (HORIZONTAL_SPLIT) y se puede cambiar para que
aparezca uno encima de otro (VERTICAL_SPLIT)
package interfacesGraficas;
import [Link].*;
import [Link].*;
MÉTODO FUNCIONALIDAD
JTabbedPane() Constructor. Se puede establecer la posición de
las solapas mediante las constantes TOP, BOTTOM,
JTabbedPane(int) LEFT y RIGTH.
package interfacesGraficas;
import [Link].*;
import [Link].*;
MÉTODO FUNCIONALIDAD
JToolBar() Constructor que crea una barra de herramientas. Se
puede especificar el nombre y la orientación de la
JToolBar(String)
barra de herramientas. Los valores posibles son
JToolBar(int) HORIZONTAL o VERTICAL.
package interfacesGraficas;
import [Link].*;
import [Link].*;
JComponent
ImageIcon
JLabel
AbstractButton
JButton
JToggleButton
JRadioButton
JCheckBox
JMenu
JMenuItem
JRadioButtonMenuItem
JCheckBoxMenuItem
JMenuBar
JPopupMenu
JSeparator
JTextComponent
JTextField
JPasswordField
JTextArea
JEditorPane
JTextPane
JList
JComboBox
MÉTODO FUNCIONALIDAD
Crea un icono desde un archivo especificado. Puede
incluir la ruta en donde se encuentra la imagen,
ImageIcon(String)
empleando como separador de directorios el carácter
‘/’.
o [Link]: esta clase implementa una etiqueta que puede contener una
cadena de texto, un icono o ambos, y puede mostrarse en cualquier contenedor.
Una etiqueta es un campo de solo salida, es decir muestra su contenido que no es
ni seleccionable ni editable por el usuario. Se emplea par dar nombre (etiquetar) a
otros componentes de la interfaz gráfica. Una característica importante de las
etiquetas en Swing es que estas admiten varias líneas, con distintos tipos de fuente.
MÉTODO FUNCIONALIDAD
JLabel(String)
Constructores. Se puede especificar el texto, el icono
JLabel(String, int)
y la alineación horizontal del contenido en la etiqueta.
JLabel(Icon)
void setText(String)
Establece u obtiene el texto de la etiqueta.
String getText()
void setIcon(Icon)
Establece u obtiene el icono de la etiqueta.
Icon getIcon()
MÉTODO FUNCIONALIDAD
JButton(String)
Constructor, en el cual se puede especificar el texto
JButton(Icon)
del botón y el icono asociado.
JButton(String,Icon)
Selecciona el botón mediante programa (equivale a
void doClick()
que el usuario haga clck sobre el botón).
Icon getIcon()
Obtiene o establece el icono del botón.
void setIcon(Icon)
String getText()
Obtiene o establece el texto del botón.
void setText(String)
boolean isSelected() Obtiene o establece el estado del botón (seleccionado
void setSelected (bolean) o no seleccionado).
boolean getEnabled() Obtiene o establece el estado de activación del botón
void setEnabled(bolean) (Activado o desactivado).
MÉTODO FUNCIONALIDAD
Constructor. Permite establecer el texto de la casilla,
JCheckBox(String, Icon, boolean) un icono y el estado inicial (true – seleccionado,
false – no seleccionado)
boolean isSelected() Obtiene o establece el estado del botón (seleccionado
void setSelected (bolean) o no seleccionado).
boolean getEnabled() Obtiene o establece el estado de activación del botón
void setEnabled(bolean) (Activado o desactivado).
JRadioButton
MÉTODO FUNCIONALIDAD
Constructor. Permite establecer el texto del botón de
JRadioBox(String, Icon, boolean) opción, un icono y el estado inicial (true –
seleccionado, false – no seleccionado)
boolean isSelected() Obtiene o establece el estado del botón (seleccionado
void setSelected (bolean) o no seleccionado).
boolean getEnabled() Obtiene o establece el estado de activación del botón
void setEnabled(bolean) (Activado o desactivado).
MÉTODO FUNCIONALIDAD
JComboBox() Constructores. El contenido inicial de la lista de
JComboBox(Object [ ]) valores se puede hacer a partir de un arreglo de
JComboBox(Vector) objetos o de un Vector.
void addItem(Object) Añade un objeto al final de la lista de valores o lo
void insertItemAt(Object,int) inserta en una determinada posición.
Obtiene un elemento de una determinada posición o
Object getItemAt(int) el elemento actualmente seleccionado del cuadro
Object getSelectedItem() combinado. Tiene los métodos set correspondientes
para establecer estos valores.
void removeItemAt(int) Elimina un objeto de la lista de la posibles valores,
void removeItem(Object) dada una posición o un objeto especifico.
void setEditable(boolean) Establece u obtiene si un campo combinado
boolean isEditable() desplegable es editable o no
Establece el número máximo de filas que muestra
para realizar la elección. Para acceder al resto
void setMaximunRowCount(int)
presenta de forma automática barras de
desplazamiento.
Ejemplo: A continuación se presenta el código que ayuda a crear un JFrame con los
componentes gráficos de Swing vistos previamente.
package interfacesGraficas;
import [Link].*;
import [Link].*;
public EjemploComponentesGraficos() {
MÉTODO FUNCIONALIDAD
JList(ListModel) Constructores. Permiten crear la lista de datos a partir
JList(Vector) de una modelo de datos, una Vector o un arreglo de
JList(Object []) objetos
void setListData(Vector)
Establece u obtiene el modelo de datos de la lista
void setListData(Object [ ])
(contenido)
ListModel getModel()
Establece u obtiene el modo de selección. Las
void setSelectionMode(int) posibilidades son: por omisión selección simple
(SINGLE_SELECTION), la selección de un único intervalo
int getSelectionMode() (SINGLE_INTERVAL_SELECTION) o la selección de intervalos
múltiples (MULTIPLE_INTERVAL_SELECTION)
int getSelectionIndex()
int getMinSelectionIndex() Obtiene el índice o valor seleccionado (o índices o
int getMaxSelectionIndex() valores dependiendo del modelo de selección que esté
int [ ] getSelectedIndices() activado). Estos métodos tienen sus métodos set
Object getSelectedValue() correspondientes para establecer estos valores.
Object [] getSelectedValues()
void clearSelection() Desactiva la selección actual o detecta si la selección
bolean isSelectionEmpty() es vacía.
El contenido de la tabla viene dado por su modelo de datos que debe implementar
la interfaz Java TableModel, aunque se proporcionan constructores y métodos que
crean automáticamente dicho modelo a partir de una matriz de objetos y de un
arreglos de objetos o a partir de dos objetos de Vector.
MÉTODO FUNCIONALIDAD
Constructor. Permite construir una tabla a partir de
JTable() una matriz que posee el contenido de la Tabla y de un
JTable(Object[][], Object[]) arreglo que contiene los encabezados de las columnas
de la tabla.
int getRowCount()
Devuelve el número de filas y columnas de la Tabla.
int getColumnCount()
Devuelve el nombre de la columna pasada por
String getColumnName(int) parámetro. Las filas y las columnas se numeran a
partir de cero (0).
Ejemplo: A continuación se presenta el código que ayuda a crear un JFrame con una
Barra de Menú y los componentes gráficos de Swing JList y JTable.
package interfacesGraficas;
import [Link].*;
import [Link].*;
import [Link];
import [Link];
public EjemploListaTabla() {
// Crear la Tabla 1
String [][] contenido = new String[][]{
{"Celda 0","Celda 1","Celda 2"},
{"Celda 3","Celda 4","Celda 5"},
{"Celda 6","Celda 7","Celda 8"}
};
String [] columnas = new String[]{"Columna 1","Columna 2","Columna 3"};
JTable jtTabla1 = new JTable(contenido,columnas);
// Crear la Tabla 2
String [][] contents = new String[5][3];
String [] colums = new String[]{"Col1","Col2","Col3"};
contents[2][2] = new String("Celda (2,2)");
JTable jtTabla2 = new JTable(contents,colums);
MÉTODO FUNCIONALIDAD
JMenuBar() Constructor no necesita parámetros
Permite añadir un menú desplegable a una barra de
void add(JMenu)
menú.
MÉTODO FUNCIONALIDAD
JMenuItem(String) Constructores. Se puede especificar el texto y un
JMenuItem(String, Icon) icono al elemento del menú desplegable.
void setEnabled(boolean) Activa o desactiva el elemento del menú
Ejemplo: A continuación se presenta el código que ayuda a crear un JFrame con una
Barra de Menú.
package interfacesGraficas;
import [Link].*;
public EjemploMenus() {
// CREAR LOS COMPONENTES DE LA VENTANA
JMenuItem itmOPC1 = new JMenuItem("Opcion 1");
JMenuItem itmOPC2 = new JMenuItem("Opcion 2");
JMenuItem itmOPC3 = new JMenuItem("Opcion 3");
JMenuItem itmOPC4 = new JMenuItem("Opcion 4");
JMenu mnu1 = new JMenu("Menu 1");
[Link](itmOPC1);
[Link](itmOPC2);
[Link](itmOPC3);
[Link](new JCheckBoxMenuItem("Opcion CHK"));
[Link](new JSeparator());
[Link](itmOPC4);
Un administrador de disposición o diseño es un objeto auxiliar que colabora con la aplicación, y con
el sistema operativo en la ésta se ejecuta, para determinar la mejor manera de mostrar los
elementos gráficos en la ventana principal de la aplicación. Un administrador de disposición permite
una mayor flexibilidad y control para colocar los componentes gráficos dentro de un contenedor, a la
vez que proporciona portabilidad e independencia frente a la plataforma concreta en la que se
ejecuta. Por ejemplo, el programador no tiene que preocuparse sobre qué pasa si el usuario cambia
el tamaño de la ventana, el tamaño de la pantalla o si su aplicación se ejecuta en Windows o UNIX.
o JPanel Æ FlowLayout
o JFrame Æ BorderLayout
o JDialog Æ BorderLayout
o JWindow Æ FlowLayout
En las primeras versiones de Java, que sólo tenían AWT, se proporcionaban de forma estándar
cinco administradores de diseño:
o FlowLayout
o BorderLayout
o GridLayout Todos los administradores implementan la interfaz LayoutManager
o CardLayout
o GridBagLayout
package interfacesGraficas;
import [Link].*;
import [Link].*;
package interfacesGraficas;
import [Link].*;
import [Link].*;
o GridLayout: con este administrador los componentes se colocan en una matriz de celdas
(definida por el número de filas y columnas) que ocupa todo el espacio asignado al
Al añadir los componentes se va rellenando la matriz primero por filas, cuando una fila está
llena se pasa a la siguiente. Proporciona dos constructores, uno en el que solo se indican el
número de filas y el número de columnas de la matriz GridLayout(int filas, int cols) y
otro en el que además, se especifica en píxeles la separación horizontal y vertical entre
celdas GridLayout(int filas, int cols, int horizontalGAP, int verticalGAP). Por lo
menos uno de los argumentos que especifican el número de filas o columnas debe ser
distinto de cero. Por omisión no hay espacio de separación entre las celdas.
Ejemplo: A continuación se presenta un ejemplo que puede ubicar nueve botones en tres
filas y tres columnas.
package interfacesGraficas;
import [Link].*;
import [Link].*;
public EjemploGridLayout() {
// Se obtiene el panel de contenido
Container panelContenido = getContentPane();
// Se añaden los botones al panel de contenido
[Link](new GridLayout(3, 3));
[Link](new JButton(“Botón 1”));
[Link](new JButton(“2 Botón”));
[Link](new JButton(“Botón 3”));
[Link](new JButton(“4 Botón”));
[Link](new JButton(“Botón 5”));
[Link](new JButton(“6 Botón”));
[Link](new JButton(“Botón 7”));
[Link](new JButton(“8 Botón”));
[Link](new JButton(“Botón 9”));
}
public static void main(String[] args) {
EjemploGridLayout Grid = new EjemploGridLayout();
[Link](“Administradores de Diseño: GridLayout”);
[Link]();
[Link](true);
}
}
METODO FUNCIONALIDAD
CardLayout() y CardLayout(int, int) Constructores. Se puede proporcionar la separación
void add(String, Object) Añade un componente al contenedor y le da nombre
void first(Container) Selecciona el primer componente, el último, el
void last(Container) siguiente o el componente anterior del mazo. Al ser
void next(Container) seleccionado se muestra automáticamente. El orden
void previous(Container) es según se han añadido al contenedor.
void show(Container, String) Muestra el componente cuyo nombre se proporciona
package interfacesGraficas;
import [Link].*;
import [Link].*;
import [Link].*;
CONSTRAINS DESCRIPCIÓN
Especifica la celda superior izquierda en el área de pantalla del
componente, donde la celda superior izquierda tiene la dirección gridx=0,
[Link] gridy=0. el valor por omisión, [Link] indica
[Link] que el componente debe simplemente colocarse a la derecha de (para
gridx) o justo debajo del (para gridy) componente que se añadió al
contenedor justo antes de que este componente fuera añadido.
Especifica el número de celdas en una fila (gridwidth) o columna
(gridheight) en el área de pantalla del componente. El valor
[Link]
predeterminado es 1. [Link] indica que el
[Link]
componente tiene que ser el último en su fila (gridwith) o columna
(wridheight).
Se utiliza cuando el área de pantalla del componente es mayor que el
tamaño solicitado del componente, a fin de averiguar si debe, y cómo,
redimensionar el componente. Los valores posibles para éste son:
[Link] (valor por omisión),
[Link] [Link] (para hacer suficientemente ancho
al componente para rellenar su área en forma horizontal),
[Link](para hacer suficientemente alto al
componente para rellenar su área en forma vertical) y
[Link] (para que rellene toda su área).
Especifica el relleno interno del componente dentro del diseño. Nos dice
cuánto más se necesita añadir al tamaño mínimo del mismo. El ancho del
[Link] componente debe ser al menos el ancho mínimo más ipadx*2 píxeles.
[Link] Esto es debido a que el relleno se aplica a ambos lados del componente.
En forma similar, la altura del componente debe ser al menos la altura
mínima más ipdy*2 píxeles.
Especifica el relleno externo del componente, la cantidad mínima de
[Link]
espacios entre el componente y los límites de su área de pantalla.
Se usa cuando el componente es más pequeño que su área de pantalla y
permite determinar dónde tiene que colocarse el componente, dentro del
área de pantalla. Los valores válidos son: GridBagConstraints..CENTER
(valor por omisión). Los otros valores válidos son:
[Link]
[Link], [Link],
[Link], [Link],
[Link], [Link],
[Link], [Link].
Permite determinar como distribuir el espacio, cuando se especifica el
comportamiento de cambio de tamaño. Si no especificamos un peso para
al menos un componente en una fila (weightx) y columna (weighty), todos
[Link]
los componentes que han sido ubicados se amontonarán en el centro del
[Link]
contenedor. Esto ocurre porque el GridBackLayout coloca todo el espacio
extra entre su malla de celdas y los límites del objeto contenedor, cuando
el peso es cero.
import [Link].*;
import [Link].*;
El usuario se comunica con una aplicación con interfaz gráfica, mediante la interacción con dicha
interfaz (por ejemplo, se pulsa el ratón o se escribe texto). Como resultado de estas acciones se
generan eventos. El tratamiento o gestión de estos eventos, mediante la ejecución de un método o
métodos en el que se responde a la acción del usuario, es la forma de obtener la interactividad de la
aplicación. Este modo de programar se denomina programación dirigida por eventos.
Esta separación entre fuente y oyente facilita la creación de código robusto para la gestión de
eventos. Además, esto permite una separación clara entre el código propio de la aplicación
(modelo), el código que genera la interfaz (vista) y el código que gestiona la interfaz
(controlador).
Objeto Fuente
LISTENER 2
(CONTROLADOR)
Se pasa el EVENTO
a los oyentes Procesa el evento
Es de hacer notar, que este modelo de tratamiento de eventos es simple pero muy versátil y fácil
de ampliar, ya que un objeto fuente puede tener registrados varios oyentes y un mismo oyente
puede estar registrado en varios objetos fuente.
Los eventos están representados en una jerarquía de clases cuya raíz es la clase
[Link]. Esta clase tiene como único atributo el objeto en el que se ha generado
el evento y proporciona el método Object getSorce(), para acceder a él. El resto de las clases
que la especializan representan tipos de eventos concretos y encapsulan toda la información
necesaria para dar respuesta a ese tipo de interacción (por ejemplo, qué botón del ratón se ha
presionado, el instante y la posición donde se ha producido, si se tenía presionado alguna trecla
modificadora tal como Ctrl. O AltGr, etc.). Esta información se obtiene mediante los métodos de
acceso correspondientes get<Atributo>().
Un objeto oyente o Listener aquel que gestiona, maneja o responde a un evento. Con este
propósito define uno o varios métodos que serán ejecutados automáticamente por la fuente de
eventos en respuesta a cada tipo de evento específico. En esta llamada automática al método
correspondiente del oyente se pasa como argumento un objeto de la clase de evento generada.
Crear una clase oyente del tipo de eventos que implemente la interfaz Java
n correspondiente.
Ejemplo: A continuación se presenta un ejemplo sencillo en el que se crea una aplicación con
una interfaz gráfica para ilustrar la gestión de eventos.
La interfaz gráfica de la aplicación consta de una ventana principal en la que se presenta una
etiqueta y dos botones. La etiqueta y los botones se agrupan añadiéndolos a un panel
contenedor que después se añade al panel de contenido de la ventana principal.
En la aplicación se incluye una clase interna que actúa como oyente de eventos de tipo acción
(ActionListener) para gestionar las interacciones con los botones. En esta clase, como respuesta
a la pulsación por parte del usuario, el programa modifica el texto de la etiqueta indicando el
botón que ha pulsado. Nótese que se registra el mismo objeto oyente en dos objetos fuente
diferentes (los dos botones). Una clase interna es muy adecuada, ya que tenemos acceso
a todos los elementos de la clase en la que está definida (en este caso la etiqueta).
package interfacesGraficas;
public EjemploEventos() {
// Se crean los componentes de la ventana
etiqueta = new JLabel("Etiqueta inicial");
botonHola = new JButton("Hola");
botonAdios = new JButton("Adios");
panel = new JPanel();
// Se añaden los componentes al panel
[Link](etiqueta);
[Link](botonHola);
[Link](botonAdios);
// Añade el panel a la venta principal
getContentPane().add(panel);
// Se crea un objeto oyente de acción que se registra en los dos botones
OyenteAccion oyenteBoton = new OyenteAccion();
[Link](oyenteBoton);
p [Link](oyenteBoton);
}
public static void main(String[] args) {
EjemploEventos ventana = new EjemploEventos();
[Link]("Ejemplo simple de Eventos");
[Link](350, 70);
[Link](true);
}
/**
* CLASE INTERNA: Se crea la Clase Oyente de Eventos de acción (ActionListener)
*/
n class OyenteAccion implements ActionListener {
public void actionPerformed(ActionEvent evento) {
// Se obtiene el botón fuente del evento
JButton boton = (JButton) [Link]();
// Tratamiento del evento
o if ([Link]().equalsIgnoreCase("Hola"))
[Link]("Se ha presionado el botón HOLA");
else if ([Link]().equalsIgnoreCase("Adios"))
[Link]("Se ha presionado el botón ADIOS");
}
}
Conceptualmente los eventos generados en los componentes gráficos se pueden clasificar en:
o Eventos de bajo nivel: éstos están relacionados con los aspectos físicos de la
interacción con los elementos de la interfaz. Representan las modificaciones en el sistema
de ventanas (por ejemplo cambio de tamaño, cambio de posición, obtención o pérdida del
foco) o las entradas producidas por el usuario (con el teclado o ratón).
o Eventos semánticos (o de alto nivel): representan la operación con un elemento de la
interfaz. Se denominan semánticos porque tratan de capturar el significado de la
interacción, por ejemplo seleccionar un elemento. No están relacionados con una clase
específica de componente, siendo aplicables a todos los componentes que implementen
un modelo de operación similar. No obstante, estos componentes no tienen que generar
dicho evento de la misma forma, por ejemplo, el evento ActionEvent se genera cuando
se hace clic sobre un botón o cuando se pulsa la tecla Intro en un campo de texto.
Un Listener es el objeto que es notificado siempre que se genera un evento. Tiene dos
requerimientos principales: el listener debe ser registrado con una o más fuentes para recibir
notificaciones cuando un evento específico se genere, y también debe implementar métodos para
recibir y procesar estas notificaciones.
Como se explico anteriormente, el modelo de delegación de eventos tiene dos partes: los objetos
fuente y los listeners. Los listeners se crean implementando una o más de las interfaces definidas
por el paquete [Link]. Cuando ocurre un evento, el fuente invoca al método apropiado
definido por el listener y le proporciona el objeto evento como su parámetro. A continuación se
listan algunos de los Listeners más importantes:
La mayoría de la interfaces oyentes están diseñadas para responder a varios eventos diferentes,
de modo que incluyen más de un método. Por ejemplo, el oyente de interacciones de ratón
(MouseListener) contiene cinco métodos relacionados con la operación de los botones y el
movimiento del mismo; esto provoca que la clase oyente deba implementarlos todos, aunque
sólo le interese alguno de ellos, y deje vacíos los otros (si no lo hace la clase sería abstracta).
package interfacesGraficas;
import [Link].*;
import [Link].*;
Los distintos componentes gráficos de una aplicación pueden generar o ser fuentes de eventos y
para cada uno de ellos se puede registrar un oyente correspondiente. Un evento que pueda
generar una clase determinada, también lo podrá generar cualquiera de sus especializaciones o
clases derivadas. Por ejemplo todos los componentes son capaces de generar FocusEvent,
KeyEvent, MouseEvent y MouseMotionEvent, ya que son los eventos generados por la clase
[Link] de la que son especializaciones los componentes gráficos.
En la Tabla siguiente se presentan los componentes de uso más frecuente junto con los eventos
que pueden generar.
JCheckBox X X X
JComboBox X X
JTextField X X
JRadioButton X X X
JList X
JTextArea X X
JMenuItem X X
JTabbedPane X
JToggleButton X X X
JPasswordField X X
JEditorPane X
Para crear un programa fuente de Java se puede utilizar cualquier editor de texto, como Bloc de
Notas. Una vez copiado el programa, se guarda el archivo con el mismo nombre de la clase
(respetando mayúsculas y minúsculas) y con extensión .java. Adicionalmente, existen editores
especializados para Java, tales como JCreator, Eclipse, NetBeans, etc., que proporcionan un IDE que
facilita el proceso de creación de programas Java.
Se procede entonces a compilar el programa copiado usando el comando javac. Este comando
genera el código binario del programa en un archivo con el mismo nombre del programa copiado
pero con extensión .class. La sintaxis del comando es la que sigue:
javac [Link]
Para ejecutar el programa, simplemente se ejecuta el comando java. Dicho comando despierta a la
JVM y es esta la que se encarga de ejecutar el programa (interpretar su código binario). La sintaxis
del comando es la que sigue:
java NombreCompletoDeLaClase
PROGRAMA
FUENTE JAVA
(.JAVA)
COMPILACIÓN
(JAVAC)
CÓDIGO BINARIO
(.CLASS)
EJECUCIÓN
(JAVA)
RESULTADOS DE LA
EJECUCIÓN
Paso 1: Haga clic en el menú Inicio y seleccione Programas Æ Accesorios Æ Bloc de Notas.
package myPack;
/**
* Ejemplo de un programa Java simple
* @autor Ronel J. Rivas R.
* @version 1.0, Septiembre de 2005
*/
public class a {
/**
* Este método transforma una cadena a un entero
* @param cad String que representa la cadena a transformar
* @return Un int que representa el valor numérico de la cadena
*/
public static int strToInt(String cad) {
return [Link](cad);
}
/**
* Programa Principal
* @param args No utilizado
* @return Nada
*/
public static void main(String[] args) {
int r = 0;
Paso 3: Una vez copiado, haga clic en Guardar en el menú Archivo. Guarde el archivo con el
nombre [Link] en el directorio Z:\myPack (si no existe el directorio, créelo).
Paso 4: Abra una consola del sistema. Para ello, haga clic en el menú Inicio y seleccione Ejecutar.
Aparecerá un cuadro de diálogo donde debe escribir cmd. Se abrirá una consola del intérprete de
comandos de Windows. Cámbiese al directorio raíz (C:\), escribiendo cd\.
Paso 6: Se ha generado el código binario. Escriba el siguiente comando para ejecutar el programa:
java SumarEnteros 1 2 4 3
La salida podrá ser vista en el intérprete de comandos, y será algo como esto: El resultado es 10
Java soporta tres tipos de comentarios.; los primeros dos son // y /* */, que permiten realizar una
aclaratoria dentro del código del programa. El tercer tipo es denominado comentario de documento,
y comienza con la sucesión de caracteres /** y finaliza con */. Los comentarios de documentación
le permiten insertar información acerca de su programa dentro de él mismo. Entonces, puede utilizar
el programa de utilidad javadoc para extraer ésta información y ponerla dentro de un archivo HTML.
Los archivos HTML generados por la aplicación javadoc, son idénticos a la documentación de la API
de Java.
Como se puede observar, todas las etiquetas de documentación comienzan con un signo @. En un
comentario de documentación, también se pueden utilizar otras etiquetas estándar
(<TAG></TAG>) de HTML. Sin embargo, algunas etiquetas tales como un título no pueden ser
empleadas, porque desorganizan la apariencia del archivo HTML producido por javadoc.
Las siguientes son algunas sugerencias en el orden de las etiquetas de documentación, a la hora de
documentar su código:
- Clases e interfaces: @see, @author, @since, @serial, @version y @deprecated
- Variables: @see, @since, @serial, @serialfield y @deprecated
- Métodos y Constructores: @see, @since, @param, @exception, @throws, @return,
@serialData y @deprecated
Después del /** inicial, la primera línea o líneas llegan a ser la descripción principal de su clase,
variable o método. Después de eso, puede incluir uno o más rótulos @ (Etiquetas). Cada rótulo @
debe arrancar al comienzo de la nueva línea, o a continuación de un asterisco (*) que está al
comienzo de la línea. Múltiples rótulos del mismo tipo deben ser agrupados juntos. Ejemplos de
Comentarios de Documentación para:
- Clase:
/**
* Esta clase dibuja un gráfico de barras
* @autor Ronel J. Rivas R.
* @version 1.0, Septiembre de 2005
*/
public class JBar {
…
}
- Variable:
/**
* Nombre del usuario, para ser utilizado en la verificación de acceso
* @see [Link]#password
*/
String userName;
- Método:
/**
* Este método introduce un número del usuario por teclado
* @param args Representa la entrada del usuario en forma de cadena
* @exception IOException En error de entrada
* @see IOException
* @return Un int que representa la entrada del usuario como número
*/
public int obtenerNumero(String args) throws IOException {
…
}
javadoc [Link]