Vous êtes sur la page 1sur 248

NOVEDADES JDK5 Y 6

1.Introducción al lenguaje Java 5


OBJETIVOS DE LA UNIDAD

 Un poco de historia
 Arquitectura de la plataforma J2SE

 Conjunto de API’s incluidas en J2SE

 Herramientas incluidas en el JDK

 Características de la Máquina virtual JVM

 Cambios en la JVM
UN POCO DE HISTORIA

 1995 (1.0) : Primera versión


 1997 (1.1) : Añadidas Clases anidadas
 2001 (1.4) : Añadidos Assertions y java.nio
 2004 (1.5-Tiger):
 Lema: Facilidad en el desarrollo
 2006 (1.6)
UN POCO DE HISTORIA
UN POCO DE HISTORIA
Assertions: Expresiones booleanas que el programador cree ser ciertos con
respecto al estado del programa.

Ejemplo: Después de la ordenación de una lista, el programador podría imponer


que la lista se encuentre en orden ascendente. La evaluación de assertions en
tiempo de ejecución para confirmar su validez es una de las mas potentes
herramientas para mejorar la calidad del software, así como destapan
rápidamente conceptos erróneos relativos al comportamiento de los
programas.

Más información: http://java.sun.com/j2se/1.5.0/docs/guide/language/assert.html


CAMBIOS INTRODUCIDOS EN TIGER

 Genéricos (Generics)
 Bucle for mejorado

 Autoboxing / Unboxing

 Tipo seguro Enums (Typesafe Enums)

 Argumentos variables en métodos (Varargs)

 Import Estáticos (Static Import)

 Anotaciones (Annotations)
ARQUITECTURA DE LA PLATAFORMA J2SE
JRE Y JDK

Sun Microsystems proporciona dos productos en su plataforma


estándar (Java SE):
- Java SE Runtime Environment (JRE)

Proporciona las librerías, Máquina virtual y otros componentes


necesarios para la ejecución de applets y aplicaciones escritas
en Java
- Java SE Development Kit (JDK)

Incluye el JRE + herramientas de desarrollo de línea de


comandos como compiladores y depuradores necesarios o
útiles para el desarrollo de applets y aplicaciones
ARQUITECTURA DE LA PLATAFORMA J2SE
CONJUNTO DE API’S INCLUIDAS

Los JSR incluidos son los siguientes:


 003 Java Management Extensions (JMX) Specification http://jcp.org/en/jsr/detail?id=3
 013 Decimal Arithmetic Enhancement http://jcp.org/en/jsr/detail?id=13
 014 Add Generic Types To The Java Programming Language http://jcp.org/en/jsr/detail?id=14
 028 Java SASL Specification http://jcp.org/en/jsr/detail?id=28
 114 JDBC Rowset Implementations http://jcp.org/en/jsr/detail?id=114
 133 Java Memory Model and Thread Specification Revision http://jcp.org/en/jsr/detail?id=133
 160 Java Management Extensions (JMX) Remote API 1.0 http://jcp.org/en/jsr/detail?id=160
 163 Java Platform Profiling Architecture http://jcp.org/en/jsr/detail?id=163
 166 Concurrency Utilities http://jcp.org/en/jsr/detail?id=166
 174 Monitoring and Management Specification for the Java Virtual Machine http://jcp.org/en/jsr/detail?id=174
 175 A Metadata Facility for the Java Programming Language http://jcp.org/en/jsr/detail?id=175
 200 Network Transfer Format for Java Archives http://jcp.org/en/jsr/detail?id=200
 201 Extending the Java Programming Language with Enumerations, Autoboxing, Enhanced for Loops and Static
Import http://jcp.org/en/jsr/detail?id=201
 204 Unicode Supplementary Character Support http://jcp.org/en/jsr/detail?id=204
 206 Java API for XML Processing (JAXP) 1.3 http://jcp.org/en/jsr/detail?id=206
HERRAMIENTAS INCLUIDAS EN EL JDK

Se encuentran las siguientes herramientas disponibles:

 Java Virtual Machine Tool Interface (JVMTI)


Interfaz para programación en el lenguaje nativo de la plataforma destinado a la creación de
herramientas de desarrollo y monitorización.
 Java Platform Debugger Architecture (JPDA)
Arquitectura para depuración multicapa que facilita la creación de herramientas de depuración
independientes de la plataforma
 Compilador (javac)
Añadidas nuevas opciones al compilador
 Herramienta javadoc
Creación de nuevos tags relacionados con los nuevos elementos.
 Annotation Processing Tool (apt)
Herramienta de comandos para el procesado de anotaciones
 JConsole
Herramienta gráfica que permite la monitorización y gestión de aplicaciones utilizando JMX.
Definición
CARACTERÍSTICAS DE LA MÁQUINA
VIRTUAL JVM

Es una máquina abstracta que contiene un conjunto de


instrucciones que le permite manipular la memoria en tiempo
de ejecución.
El bytecode generado en el proceso de compilación es
interpretado por la máquina virtual.
Existen implementaciones de la máquina virtual para diferentes
plataformas, proporcionando independencia del sistema
operativo y el hardware
Write once run anywhere
Implementaciones
CARACTERÍSTICAS DE LA MÁQUINA
VIRTUAL JVM

La plataforma estándar proporciona dos implementaciones de máquina virtual:


- Java HotSpot Client VM
Implementación para plataformas utilizadas para aplicaciones cliente reduce el
tiempo de arranque y la cantidad de espacio en memoria. Puede ser invocada
mediante la opción –client al arrancar una aplicación.

- Java HotSpot Server VM


Implementación diseñada para proporcionar la máxima velocidad de ejecución de
programas a costa de memoria y tiempo de arranque. Puede ser invocada
mediante –server cuando se lanza una aplicación.
Mejoras

CAMBIOS EN JAVA VIRTUAL MACHINE

 En JDK 6.0:
 DTtrace Probes

 Garbage Collection Enhancements

 Parallel Compaction

 Mejoras en Concurrent Mark Sweep Collector

 En JDK 5.0:
 Class Data Sharing

 Server-Class Machine Detection

 Garbage Collection Ergonomics

 Thread Priority Changes

 Otras mejoras

Fuente:http://java.sun.com/javase/6/docs/technotes/guides/vm/index.html
Mejoras en JDK 5.0
CAMBIOS EN JAVA VIRTUAL MACHINE

Class Data Sharing


Consiste en el volcado de determinadas clases core a un archivo que será compartido por todas las instancias
de las máquinas virtuales. Además este archivo está diseñado para ser leído directamente por un
HotSpot.

Ventajas
- Disminución del tiempo de arranque de la máquina virtual.
- Al compartir todas las instancias el mismo archivo eliminamos la duplicidad que existía antes al
tener que cargar todas las clases por instancia de máquina virtual.

Inconvenientes
- No soportado en Windows 95/98/ME
- Solo disponible en VM Client
- Solo disponible con el Garbage Collector de serie

Fuente:http://java.sun.com/javase/6/docs/technotes/guides/vm/class-data-sharing.html
Mejoras en JDK 5.0

CAMBIOS EN JAVA VIRTUAL MACHINE

Server-Class Machine Detection


Detección automática en el arranque del tipo de máquina virtual que debe arrancar
(vm client o vm server) en función de las especificaciones.
Al arrancar en el modo mas óptimo para el hardware se consigue aumentar el
rendimiento. La deducción se basa en la configuración de la plataforma (hardware
+ sistema operativo), algo normalmente poco fiable y variable en el tiempo.
En Java 6.0 una máquina servidora es aquella con 2CPU y al menos 2GB de memoria.

http://java.sun.com/javase/6/docs/technotes/guides/vm/server-class.html
Mejoras en JDK 5.0

CAMBIOS EN JAVA VIRTUAL MACHINE

Garbage Collection Ergonomics


El parallel collector ha sido mejorado para adaptarse a las necesidades de memoria de la
aplicación.

Se puede especificar el tipo de rendimiento que queremos en la aplicación y automáticamente la


maquina virtual optimizará el tamaño del heap para conseguir los objetivos de rendimiento.

Con esto se evita el ajuste manual por línea de comandos que se necesitaba hasta ahora.
Mejoras en JDK 5.0
CAMBIOS EN JAVA VIRTUAL MACHINE

Thread Priority Changes


Cambio en el mapeo de la prioridad de los hilos. Ahora los hilos Java y los nativos compiten en
igualdad asociando cada hilo Java con un hilo nativo únicamente.
La relación entre el hilo Java y el hilo nativo es estable y persiste a lo largo del tiempo de vida del
hilo Java.

http://forums.sun.com/thread.jspa?forumID=31&threadID=550529
http://www.javaworld.com/javaworld/jw-09-1998/jw-09-threads_p.html

Otras mejoras
 El mecanismo de aviso de errores fatales ha mejorado en el diagnóstico y fiabilidad.
 Soporte de granularidad de nanosegundos para mediciones de tiempos (dependiente
de plataforma).
Mejoras en JDK 6.0

CAMBIOS EN JAVA VIRTUAL MACHINE

DTrace Probes
Es una herramienta de instrumentación desarrollada por Sun en el 2005 y disponible en Solaris
10. DTrace está formado por una serie de elementos, el uso de los cuales nos permiten
medir, controlar, registrar, etc. variables del sistema. Cuando utilicemos DTrace debes pensar
(la misma nomenclatura de DTrace nos lleva a ello) que estamos poniendo sondas en el
sistema que están recogiendo datos para nosotros.
Está orientada tanto para desarrolladores, a los cuales puede ayudar en las distintas fases de
desarrollo, midiendo variables del sistema, de la misma forma que ocurriría en un sistema
en producción.

Mas información:
Solaris Dynamic Tracing Guide:
http://docs.sun.com/app/docs/doc/819-3620

DTrace Probes in HotSpot VM:


http://java.sun.com/javase/6/docs/technotes/guides/vm/dtrace.html
Mejoras en JDK 6.0
CAMBIOS EN JAVA VIRTUAL MACHINE

Mejoras en el Garbage Collector


- Parallel Compaction
- Concurrent Mark Sweep Collector Enhancement
Mejoras en JDK 6.0

CAMBIOS EN JAVA VIRTUAL MACHINE

Mejoras en el Garbage Collector


- Parallel Compaction Collector
Complementa al GC paralelo existente a partir de Java 5.0 update 6. Utilizado en entornos
multiprocesador. Realiza “Full GC” en paralelo. Durante un “Full GC” toda la memoria “heap” es
revisada y liberada.
En Java 5.0 el GC solo era capaz de realizar en paralelo “Young GC” en la que solo son liberados los
recursos generados de forma mas temprana.
Por defecto no está habilitado, aunque en futuras versiones es posible que sea una opción por
defecto. Para habilitarla deberemos incluir -XX:+UseParallelOldGC al comando java de
lanzamiento.
Mas información:
http://java.sun.com/javase/6/docs/technotes/guides/vm/par-compaction-6.html
https://java.sun.com/j2se/reference/whitepapers/memorymanagement_whitepaper.pdf
Mejoras en JDK 6.0
CAMBIOS EN JAVA VIRTUAL MACHINE

Mejoras en el Garbage Collector

- Concurrent Mark Sweep Collector Enhancement (Concurrent Low Pause Collector)


Conocido como recolector paralelo de pausa baja o CMS. Está destinado a aplicaciones que son sensibles a
pausas prolongadas provocadas por el GC potenciando la actividad del GC concurrentemente. Utilizado en
máquinas con múltiples procesadores.
La llamada al GC mediante System.gc() o Runtime.getRuntime().gc() para que libere todos los objetos que no
son usados, realiza una parada en todas las aplicaciones lo que provoca una pérdida de rendimiento
cuando el uso la memoria “heap” es elevado.
Beneficios
- El objetivo del CMS es reducir estos tiempos en pausas mas cortas.
- Aumento del tamaño de “young generation” cuando el CMS es usado (4MB a 16MB)
- Marcado paralelo de objetos no usado (Full GC). En versiones anteriores todo se realizaba en un solo
hilo.
Mejoras en JDK 6.0
CAMBIOS EN JAVA VIRTUAL MACHINE

Fuente: http://java.sun.com/performance/reference/whitepapers/6_performance.html
2.Fundamentos del lenguaje
OBJETIVOS DE LA UNIDAD

 Tipos de datos Wrapper


 Métodos con argumentos variables (varargs)

 El metadata y las Annotations

 Uso de Genéricos

 Conversiones automáticas y Casting

 Boxing y Unboxing, conversiones unboxing.

 Clases String, StringBuffer y StringBuilder

 Buenas prácticas con java.lang


TIPOS DE DATOS WRAPPER

Los Wrappers (envoltorios) son clases diseñadas para ser un complemento


de los tipos primitivos.
Los tipos primitivos tienen ventajas de eficiencia, pero carecen de ciertas
funcionalidades:
- Los tipos primitivos siempre se pasan como argumento a los
métodos por valor, mientras que los objetos se pasan por referencia.
- Las clases Wrapper también proporcionan métodos para realizar
conversión con cadenas de caracteres en uno y otro sentido.
Existe una clase Wrapper para cada uno de los tipos primitivos numéricos
(Byte, Short, Integer, Long, Float y Double)
TIPOS DE DATOS WRAPPER
Características

- Todas las clases Wrapper heredan de java.lang.Number.


- Sus constructores permiten creación del Wrapper desde String y desde el tipo
primitivo.
Ej: Double(double value) y Double(String value)
- Poseen métodos xxxxValue de conversión a tipos primitivos.
Ej: byte byteValue(), double doubleValue(), etc.
- Poseen método toString().
- Poseen método boolean isNaN() para comprobar si el valor es numérico.
- Poseen métodos estáticos de conversión de:
 Tipo primitivo a Wrapper: valueOf

 String a Wrapper: valueOf

 String a tipo primitivo: parseXXXXX (parseDouble)

Veamos algunos ejemplos a continuación.


TIPOS DE DATOS WRAPPER
Clase Double

Constructores
Double (double value) y Double(String value)

Métodos conversores a tipos primitivos (xxxValue)


byte byteValue(), double doubleValue(), float floatValue(), int intValue(), static double
parseDouble(String s)

Métodos conversores a Wrapper


static Double valueOf(double d)
static Double valueOf(String s)

Método de conversión a cadena


String toString()

Ver javadoc del resto de Wrappe


MÉTODOS CON ARGUMENTOS VARIABLES
(VARARGS)
varargs se denomina a la posibilidad de declarar que un método admita varios
argumentos de un mismo tipo sin determinar la cantidad exacta.

Sintaxis: NombreTipo... nombreArgumento


Ejemplo:
public void enviarEmail(String asunto,String... emails)

enviarEmail("Saludo","pepe@dominio.com","juan@dominio.com");

El compilador determina qué valores de los pasados al método corresponden al


argumento variable y forma un array con ellos.
MÉTODOS CON ARGUMENTOS VARIABLES
(VARARGS)
Restricciones

 Sólo puede haber un argumento variable en un método.


 El argumento variable tiene que ser el último del método.
 Es posible no proporcionar valor alguno para el argumento variable.
Ejemplo:
enviarEmail("Saludo");
 Acceso a los valores del argumento variable mediante un array de valores.
Ejemplo:
public void enviarEmail(String asunto, String... emails){
for (int i = 0; i < emails.length; i++) {
..
}
METADATA Y ANOTACIONES

Definición
Las anotaciones permiten asociar información, en forma de pares atributo-valor
(miembros), a los elementos de programación (paquetes, tipos, métodos,
constructores, campos, parámetros y variables locales).
Las anotaciones son meta información (información sobre el código).
Un tipo de anotación (annotation type) es a una anotación lo que a un objeto es
su clase.
Se define como una interfaz especial con restricciones y diferente sintaxis, se
verá su definición más adelante.
METADATA Y ANOTACIONES

Las anotaciones no modifican la ejecución de un programa, por lo


que sólo tienen sentido para programas o herramientas que las
extraigan e interpreten.

Un ejemplo es el compilador, que procesa varios tipos de


anotaciones predefinidas.

El JDK proporciona un framework para herramientas de


procesado de anotaciones llamado apt.
METADATA Y ANOTACIONES

La nueva Java Reflection API de J2SE 5.0 soporta anotaciones por


lo que se puede tener acceso a las anotaciones en tiempo de
ejecución.

Los miembros de un tipo de anotación son los pares atributo-valor


que soporta.

Una anotación marcador (marker annotation) es un tipo de


anotación que no declara ningún miembro, la información que
aporta al elemento es su presencia o ausencia.
METADATA Y ANOTACIONES

Uso de anotaciones
Sintaxis
@TipoAnotacion(nombre1=valor1,nombre2=valor2,...)
El orden de los pares no es importante. Si un miembro tiene valor
por defecto no es obligatoria su presencia.

Si el tipo de anotación es marcador, no tiene miembros, no son


necesarios los paréntesis.
@TipoAnotacion
METADATA Y ANOTACIONES

Uso de anotaciones
Sintaxis (continuación)
Si el tipo tiene un único miembro y tiene de nombre value, podría suprimirse el nombre y
el símbolo =.
@TipoAnotacion(valor)

Si el tipo de un miembro es un array de elementos, se pasan los valores entre llaves y


separados por comas.
@TipoAnotacion(....,nombren={subvalor1,subvalor2,...},...)

Si además sólo se quiere pasar un valor en el array no son necesarias las llaves.
@TipoAnotacion(....,nombren=subvalor,...)
Los valores tienen que coincidir con el tipo del miembro declarado en su definición.
METADATA Y ANOTACIONES

Uso de anotaciones
Colocación
Se colocan justo antes de los modificadores de los elementos del lenguaje, normalmente en la
línea anterior a la del elemento.

Un caso especial son los paquetes, que como no son declarados en ningún sitio, es necesario para
asignarles una anotación, crear un fichero llamado package-info.java donde se declara el
paquete y se antepone la anotación.

También hay que apuntar que los valores enumerados, a pesar de no tener modificadores, pueden
ser anotados normalmente.

Un elemento no puede tener más de una instancia de un tipo de anotación.


METADATA Y ANOTACIONES

Anotaciones Estándar
Forman parte del paquete java.lang y son evaluadas por el compilador.
@Override
Avisa al compilador que el método al que acompaña sobrescribe un método de la
superclase. Aviso en tiempo de compilación por parte del compilador.
Ej:
@Override
public String toString() {
....
METADATA Y ANOTACIONES

Anotaciones Estándar
@Deprecated
Avisa al compilador de que un elemento es obsoleto, que se desaconseja su uso. De la misma
forma que lo hace la etiqueta @deprecated a la herramienta javadoc. El compilador lanzará un
warning, cuando se esté usando un elemento obsoleto en código no obsoleto.
Deprecated es una anotación marcador y se puede aplicar a cualquier elemento.
Ej:
@Deprecated
public enum FormatoAudio {..}
METADATA Y ANOTACIONES

Anotaciones Estándar
@SupressWarnings
Tipo de anotación que indica al compilador qué tipo de warnings no debe lanzar de las
generadas en el elemento anotado.
Se utiliza cuando el programador es consciente de que esta haciendo una práctica
desaconsejada pero por circunstancias es necesario, de esta forma en una zona
determinada del código se deshabilita al compilador para generar warnings de un tipo.
SuppressWarnings tiene un miembro cuyo tipo es un array de Strings, que contendrá los
identificadores de los warnings que se quieren evitar. Actualmente los identificadores no
están especificados por lo que se depende de la implementación del compilador. Algunos
implementados son: all, deprecation, checked, fallthrough, path, serial, finally.
Se puede aplicar a casi todos los elementos: tipos, campos, métodos, parámetros,
constructores y variables locales.
METADATA Y ANOTACIONES

Anotaciones Estándar
@SupressWarnings
Ej: Array de elementos
@SuppressWarnings({"checked","finally"})
public enum FormatoAudio {..}

Incluso si el array que se quiere pasar tiene sólo un elemento, no son


necesarias las llaves:
@SuppressWarnings({"all"})
public enum FormatoAudio {..}
METADATA Y ANOTACIONES

Creación de anotaciones
Un tipo de anotación es una interfaz especial. Se define con la palabra clave @interface, que
implícitamente extiende la interfaz java.lang.annotation.Annotation.
Si se extiende manualmente no se crea un tipo de anotación.

Los miembros del tipo se definen como métodos sin parámetros, donde:
- Nombre del miembro es nombre del método.
- Tipo del miembro es tipo de retorno del método (primitivo, String, Class, un tipo
enumerado, un tipo de anotación o un array simple de un tipo de los anteriores).

Valor por defecto mediante palabra reservada default:


Ej: boolean devbuild() default false;
Null no es un valor por defecto válido.
METADATA Y ANOTACIONES

Creación de anotaciones

El único miembro de tipo que puede ser parametrizado es Class.


Como cualquier interfaz, un tipo de anotación puede definir constantes y
miembros estáticos y puede ser implementada o extendida.

Un tipo de anotación puede ser anotada en su definición por meta-anotaciones


(anotaciones para anotaciones).
METADATA Y ANOTACIONES

Meta-anotaciones
Son anotaciones aplicables a anotaciones que se
pueden usar en la definición de la anotación
para caracterizarlas.
Java 5.0 define cuatro meta-anotaciones
estándar dentro del paquete
java.lang.annotation:
- Target
- Retention
METADATA Y ANOTACIONES

Meta-anotaciones
Target
Meta-anotación que especifica los elementos "objetivo" del tipo de anotación
que está siendo definida. O sea los elementos del lenguaje que pueden ser
anotados por el tipo.
Si un tipo de anotación no tiene la meta-anotación Target, esta puede ser
usada en cualquier elemento del lenguaje.
Target tiene un único miembro de nombre value y de tipo
java.lang.annotation.ElementType[] , un array de un tipo enumerado que
representa los elementos del lenguaje.
METADATA Y ANOTACIONES

Meta-anotaciones
Retention
Especifica el alcance del tipo de anotación que está siendo definida. Tiene un único miembro
llamado value, de tipo java.lang.annotation.RetentionPolicy con estos valores posibles:
 SOURCE La anotación sólo existe en el código fuente, no pasa a la clase compilada.

 CLASS La anotación se registra en la clase, pero la máquina virtual la ignora en


tiempo de ejecución (valor por defecto)
 RUNTIME Además de quedar registrada en la clase, la máquina virtual la retiene en
tiempo de ejecución siendo accesible reflexivamente.
Nota: El formato de fichero class no es capaz de almacenar anotaciones para las variables locales.
Por lo tanto aunque una variable local este acompañada por una anotación de alcance CLASS
o RUNTIME, no será efectivo, quedándose siempre en SOURCE.
METADATA Y ANOTACIONES

Meta-anotaciones
Documented
Especifica que el tipo de anotación definida debe formar parte de la
documentación generada por herramientas como javadoc.
Documented es una anotación marcador, no tiene miembros.

Inherited
Inherited es una anotación marcador que especifica que el tipo de anotación
definido es heredado.
Quiere decir que la anotación aplicada a una clase se aplicará también a sus
subclases.
METADATA Y ANOTACIONES

Ejemplo

package java.lang;
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
METADATA Y ANOTACIONES

Anotaciones y Reflection API


La Reflection API de J2SE 5.0 ha sido modificada para soportar
anotaciones visibles en tiempo de ejecución (retention =
RUNTIME).
La interfaz que permite leer reflexivamente las anotaciones es
java.lang.reflect.AnnotatedElement.
Es implementada por las diferentes clases que permiten el acceso
a los elementos; java.lang.reflect.Field,
java.lang.reflect.Method, etc.
USO DE GENÉRICOS (GENERICS): VISIÓN
GENERAL

1) Introducción a los tipos genéricos


2) Uso de tipos genéricos
3) Aspectos avanzados en el uso de genéricos
 Raw Types

 Jerarquía de tipos genéricos

 (In)Seguridad de tipos en tiempo de ejecución

 Arrays de tipos parametrizados

 Comodín de tipo (Type Parameter Wildcard)

4) Definición de tipos genéricos


5) Métodos genéricos
6) Excepciones parametrizadas
USO DE GENÉRICOS (GENERICS)
1) Introducción a los tipos genéricos

 El soporte en el lenguaje de tipos y métodos genéricos es la


característica más importante incorporada en la nueva versión
de Java. Además se complementa muy bien con otras nuevas
funcionalidades como varargs, anotaciones, tipos
enumerados, etc.
 Un tipo genérico permite controlar el tipo de los objetos con los
que trabajan sus instancias cuando en su definición (del tipo
genérico) no se quiere concretar (el tipo de los objetos) para
hacerlo más general.
 Un ejemplo claro de uso de genéricos es la librería de
colecciones. Se usarán tipos de esta para los ejemplos de uso.
USO DE GENÉRICOS (GENERICS)
1) Introducción a los tipos genéricos

Especialmente útil en manejo de colecciones al poder indicarle al


compilador que tipo contiene una colección.
Al obtener un elemento desde una colección es necesario realizar
casting pero:
 Es pesado
 Es inseguro, pueden fallar en tiempo de ejecución.

Por tanto:
 Compilador realiza el casting.
 Asegura que este se produce correctamente.
 Ahorro de esfuerzos en desarrollo y depuración
USO DE GENÉRICOS (GENERICS)
2) Uso de tipos genéricos

Sin genéricos:
List lista= new LinkedList();
lista.add("Hola");
String elemento= (String)lista.get(0);

Con genéricos:
List<String> listaDeStrings= new LinkedList<String>();
listaDeStrings.add("Hola");
String elemento= listaDeStrings.get(0);
USO DE GENÉRICOS (GENERICS)
2) Uso de tipos genéricos

Con genéricos:
Map<String,List<Map<String,int[]>>> estructuraCompleja = new
HashMap<String,List<Map<String,int[]>>>();
int i= estructuraCompleja.get(clave1).get(0).get(clave2)[0];

Sin genéricos:
int i=
((int[])((Map)((List)estructuraCompleja.get(clave1)).get(0)).get(clave2))[0];
USO DE GENÉRICOS (GENERICS)

3) Aspectos avanzados
Veremos cuestiones relativas al uso de genéricos.
Raw Types
Nos permite instanciar objetos del API Collection
objetos sin necesidad de indicar su tipo.
Permite la compatibilidad hacia versiones
anteriores.
No existe mucha justificación en el uso de Raw
Types en código nuevo de Java 5.
USO DE GENÉRICOS
3) Aspectos avanzados
(GENERICS)

Jerarquía de tipos
La jerarquía de los tipos genéricos es
independiente de la jerarquía de sus tipos
parametrizados.

En general, si B es subtipo (subclase o


subinterfaz) de A y G es una declaración de un
tipo genérico, G<B> no es un subtipo de G<A>
USO DE GENÉRICOS
3) Aspectos avanzados
(GENERICS)

Jerarquía de tipos
Un ejemplo: ¿Son correctas estas líneas de código?
List<String> ls = new ArrayList<String>(); //1
List<Object> lo = ls; //2

¿Una Lista de String es una Lista de Objetos?

Aunque la intuición nos diga que es correcto, no es posible ya que si esto


fuera cierto podríamos introducir dentro de ls cualquier tipo de objeto
permitiendo un problema de seguridad de tipos.
USO DE GENÉRICOS
3) Aspectos avanzados
(GENERICS)

(In)Seguridad de tipos en tiempo de ejecución


Consecuencia de la existencia de Raw Types.
Es posible generar en tiempo de ejecución (ClassCastException). Posibilidad de convertir un tipo parametrizado
en no parametrizado.
List<String> listaDeStrings= new ArrayList<String>();
List lista= listaDeStrings;
lista.add(new Integer(1));
String s0= listaDeStrings.get(0); // ClassCastException en ejecución

El compilador avisa pero lo permite por compatibilidad hacia atrás.


Existen en la clase java.util.Collections varios métodos
(chequedList,chequedMap...) que comprueban la seguridad de tipos en tiempo de ejecución en los
ejemplares que devuelven.
USO DE GENÉRICOS
3) Aspectos avanzados
(GENERICS)

Arrays de tipos parametrizados.


En Java, un array de un tipo es también un array de una superclase o interfaz de ese tipo. Así, el
intérprete tiene que analizar en tiempo de ejecución el tipo de los objetos que se intentan
introducir.
String[] palabras = new String[10];
Object[] objetos = palabras;
objetos[0] = new Integer(1); // lanza una ArrayStoreException
En la ejecución el ejemplo anterior, el intérprete sabe que objetos es un array de String y al
comprobar que el objeto a asignar es de otro tipo (Integer) lanza una excepción.
USO DE GENÉRICOS
3) Aspectos avanzados
(GENERICS)

Arrays de tipos parametrizados.


Con los tipos genéricos esta protección en tiempo de ejecución no es suficiente, ya que el
control de tipos se efectúa en tiempo de compilación. La consecuencia sería otro
agujero en el control de tipos.
Para evitarlo el compilador no permite declaraciones de arrays de tipos parametrizados:
List<String>[] listaDeStrings = new ArrayList<String>[10]; // Error
de compilacion
aunque sí de tipos genéricos sin parametrizar (por compatibilidad hacia atrás), de esta
desaconsejable forma:
List[] lista= new ArrayList[10];
USO DE GENÉRICOS
3) Aspectos avanzados
(GENERICS)

Comodín de tipo (Type Parameter Wildcard)


Cuando se necesita que un método cualquiera (no tiene que ser genérico) admita cualquier instancia
de un tipo genérico (parametrizada con cualquier tipo) como parámetro, es posible usar el
comodín de tipo o tipo desconocido. Se representa con el carácter ?, en vez de un tipo concreto.
Como ejemplo el método reverse de la clase java.util.Collections
static void reverse(List<?> lista)
Con el comodín de tipo se logra que el método invierta el orden listas parametrizadas con cualquier
tipo.
USO DE GENÉRICOS
3) Aspectos avanzados
(GENERICS)

Comodín de tipo (Type Parameter Wildcard)


Comodín de tipo limitado
Es posible usar el concepto de comodín de tipo pero limitándolo a
determinadas clases, las que descienden o son superclases de una dada.
 Limitación superior (<? extends Superclase>): Clases posibles solo las
derivadas de Superclase (incluyendo a la propia clase).
 Limitación inferiormente (<? super Subclase>), en este caso las clases
posibles serán superclases de la dada.
USO DE GENÉRICOS
4) Métodos genéricos
(GENERICS)

Los métodos genéricos son métodos que tienen declaradas sus propias variables de tipo.
El ejemplo típico son los métodos estáticos, que por su naturaleza estática, no pueden acceder a las variables de
tipo declaradas en su clase, pero sí pueden tener sus propias variables de tipo.

Definición
modificadoresMetodo <A,B,..> TipoRetorno nombreMetodo(arg1,arg2,..)
USO DE GENÉRICOS
4) Métodos genéricos
(GENERICS)

Ejemplo:
public static <N extends Number> Pila<N> mayorSumatorio(Pila<N> p1, Pila<N> p2) {
Pila<N> pilaResultado= null;
if (sumatorio(p1) > sumatorio(p2)) pilaResultado= p1;
else if (sumatorio(p1) < sumatorio(p2)) pilaResultado= p2;
return pilaResultado;
}
Uso:
Pila<Double> p1= new Pila<Double>();p1.aniadir(111.2);
Pila<Double> p2= new Pila<Double>();p2.aniadir(2.2);
Pila<Double> p3= Pila.mayorSumatorio(p,p2);

El compilador deduce que el tipo parametrizado es Double, por lo que no es necesario ponerlo, aunque tampoco
sería incorrecto:
Pila<Double> p3= Pila.<Double>mayorSumatorio(p,p2);
USO DE GENÉRICOS (GENERICS)
5) Excepciones parametrizadas

 Las excepciones son clases que se generan y capturan en tiempo de


ejecución, por lo que es imposible para el compilador controlar los tipos de
excepciones parametrizadas. Por este motivo no es posible introducir
variables ni comodines de tipo en los bloques catch.
 En conclusión, no es posible hacer genérico ningún tipo derivado de
Throwable, por lo que las excepciones parametrizadas no están permitidas.
 Para profundizar consultar las implementaciones de la librería estándar de
Java 5 java.util, java.lang, java.lang.reflect y java.util.concurrent.
USO DE GENÉRICOS (GENERICS)

En resumen:

 Mas claro y seguro


 No es necesario realizar casting, variables
temporales, etc.
 Proporciona comprobación de tipos en tiempo de
compilación.
 Genericidad en la construcción de clases.
USO DE GENÉRICOS (GENERICS)

Ejercicio:

 Creación de un DAO utilizando los genéricos.


 Creación de una estructura pila.
 Añadir
 Extraer
 Está vacía
BOXING Y UNBOXING

 La conversión de un valor de tipo primitivo a una instancia de su clase


wrapper (boxing) y al contrario (unboxing) es una tarea engorrosa. En
J2SE 5.0 ambas conversiones son automáticas. A esta nueva facilidad
se le llama Autoboxing.

 Elimina la conversión manual entre tipos primitivos y los tipos envoltorio


(wrappers) correspondientes, por ejemplo entre int e Integer. Ahora la
conversión entre tipos primitivos y objetos es automática si necesidad de
código de conversión.

 Esto facilita la integración con las herramientas de desarrollo.


BOXING Y UNBOXING

Hasta ahora:
Integer iObject= new Integer(1); // boxing
int i= iObject.intValue(); // unboxing

Con autoboxing:
Integer iObject= 1; // auto-boxing
int i= iObject; // auto-unboxing
BOXING Y
Implicaciones
UNBOXING

1. Auto-unboxing de valores null producen NullPointException


Integer iObject= null;
int i= iObject; // Se lanza una NullPointerException

2. Operaciones de los tipos primitivos disponibles para las clases Wrapper


(autoboxing)

Integer iObject= 0;
Integer iObject1= 1;
Integer iObject2= iObject+iObject1;
iObject2++;

Boolean boolObject = true;


boolean bool = false;
Boolean result = (boolObject || bool) && boolObject;
BOXING Y
Implicaciones
UNBOXING

3. Operador ==. Uso distinto en primitivos y objetos


Solo se realiza auto-unboxing cuando uno de los operandos es primitivo.

Integer iObjeto1 = 1000;


Integer iObjeto2 = 1000;
int i1= 1000;
int i2= 1000;
(i2 == i1)
// resultado= true
(i2 == iObjeto1)
// resultado= true, auto-unboxing de iObjeto1
(iObjeto2 == iObjeto1)
// resultado= false, no hay auto-unboxing, comparacion de objetos
BOXING Y
Implicaciones
UNBOXING

4. Resolución de métodos
Cuando hay sobrecarga de métodos la resolución se basa en los argumentos, pero con la aparición del
autoboxing se pueden dar casos de ambigüedad.

Ejemplo:
public static void nombreMetodo(int i)
public static void nombreMetodo(Integer iObjeto)
// LLamada al metodo, no se aplica autoboxing
NombreClase.nombreMetodo(1);

Si existe ambigüedad no se aplica el autoboxing. En caso de no haberla, se aplica el autoboxing normalmente.

Ejemplo:
public static void nombreMetodo(Integer iObjeto)
// LLamada al metodo con autoboxing
NombreClase.nombreMetodo(1);
String

STRING, STRINGBUFFER Y STRINGBUILDER

Una de las clases mas importantes. Sus características mas importantes son:
1.- Implementa el patrón de diseño inmutable que indica que un objeto no puede ser
modificado, por tanto, al modificar cadenas realmente se están creando objetos
nuevos.

String s1 = “bienvenido”;
s1.concat(“ amigo”);
System.out.println(s1); ¿Salida por pantalla?

2.- Comparación de cadenas siempre con equals, nunca utilizar ==.


StringBuffer

STRING, STRINGBUFFER Y STRINGBUILDER

Está diseñada para manejar cadenas de caracteres que deban cambiar varias veces durante
la ejecución de un programa. Todas las modificaciones quedan dentro del mismo objeto.
Es una clase sincronizada.

Diferencias:
StringBuffer sb = new StringBuffer(“hola”);
sb.append(“ caballero”);

String st =“hola”;
st +=“ caballero”; //st = st.concat(“caballero”);

¿Cuántos objetos se están creando en cada caso?


StringBuilder
STRING, STRINGBUFFER Y STRINGBUILDER

Nueva clase no sincronizada (synchronized) que modela una secuencia


modificable de caracteres. Sustituye a la clase StringBuffer en la
programación no concurrente

Métodos más importantes:


- append (String str): Añade texto al final de la cadena.
- insert (int pos, String str): Añade la cadena en la posición concreta
BUENAS PRÁCTICAS CON JAVA.LANG

1. Creación de cadenas con operador =.


2. Utilización de StringBuffer y StringBuilder para manejo de cadenas.
3. Utilización de StringBuilder en lugar de StringBuffer para programas no
concurrentes.
4. Comparación de cadenas con equals.
5. Evitar errores en tiempo de ejecución (NullPointException).
1. Antes de usar un objeto compararlo con null
2. Invertir orden en comparación con equals
6. Utilizar Wrappers para identificadores únicos puede ser en determinadas
ocasiones útil.
7. Buen uso de la herencia con Object (toString, clone, hashCode, etc)
8. Utilización de Autoboxing siempre que sea posible.
3. Estructuras condicionales y bucles
OBJETIVOS DE LA UNIDAD

 Uso de static, native, strictfp y volatile.


 Uso del nuevo bucle for (foreach).

 Lista de parámetros y promociones directas.

 Tipo de retorno de datos y promoción interna.


MODIFICADORES EN JAVA
Modificadores de acceso

NOMBRE APLICADO A CLASE APLICADO A MÉTODO APLICADO A


PROPIEDAD
public Acceso a la clase desde cualquier Acceso desde cualquier clase, en Acceso desde cualquier
otra. cualquier lugar. clase, en cualquier
lugar.

protected Miembro es accesible dentro del Puede ser accedido por métodos de Puede ser accedido por
mismo paquete y dentro de una la misma clase o de una métodos de la misma
subclase. subclase. clase o de una subclase.

Blank Miembro solo acceso dentro del Solo acceso por métodos dentro del Solo acceso por métodos
(friendly) mismo paquete mismo paquete solamente. dentro del mismo
paquete solamente.

private Miembro solo es accesible desde la Solo acceso por métodos de la Solo acceso por métodos de
clase que lo define misma clase la misma clase
MODIFICADORES EN JAVA
Modificadores de comportamiento

NOMBRE APLICADO A CLASE APLICADO A MÉTODO APLICADO A PROPIEDAD

static Utilizado para declarar No necesario instanciar clase para su Solo existe una por instancia
clase de nivel superior llamada. por máquina virtual.
en contraposición a una NombreClase.nombreMétodo.
clase interna (inner- Solo acceso a variables static
class)

abstract La clase no puede Método está definido pero sin No aplica


instanciarse. Utilizado implementación. Solo pueden
para herencia. aparecer en clases abstract

final La clase no puede utilizarse Método no puede ser sobreescrito. El valor no puede ser
en herencia (extends) modificado. CONCEPTO
DE CONSTANTE.

stricfp Operaciones en coma Operaciones en coma flotante mediante No aplica


flotante mediante IEEE-754
IEEE-754
MODIFICADORES EN JAVA
Modificadores de comportamiento

NOMBRE APLICADO APLICADO A MÉTODO APLICADO A PROPIEDAD


A CLASE
synchronized No aplica Método se bloquea y solo No aplica
permite ejecutarse por
un hilo simultaneamente

native No aplica Implementación del método No aplica


se encuentra en código
nativo (JNI)

transient No aplica No aplica Campo no será serializado.

volatile No aplica No aplica Indica que Java leerá la variable dessde


memoria no desde ninguna caché.
Asegura valor exacto en concurrencia.
MODIFICADORES EN JAVA
MODIFICADORES
Bloques EN
de código {..} JAVA

1. Bloque Static
Se ejecuta la primera vez que se crea un objeto de una clase o se llama a uno de
sus métodos static.
static{
//Instrucciones
}
2. Bloque Synchronized
Bloquea el trozo de código situado en su interior permitiendo que un solo hilo
simultáneamente lo ejecute.
synchronized(this){
//Sección crítica
}
MODIFICADORES EN JAVA

Reglas
1. La declaración de un método puede contener uno de los modificadores de acceso:
public, protected y private.
2. Las clases no pueden declararse como abstract y final simultáneamente.
3. Los métodos abstract no pueden declararse como private, static, final, native, strictfp o
synchronized.
4. Los métodos no pueden declararse como native y strictfp simultáneamente.
5. Los métodos abstract y native no tienen cuerpo:
abstract void method();
native void method();
6. Una clase que contiene métodos abstract debe ser declarada abstract
7. Campos final no pueden ser volatile
USO DEL NUEVO BUCLE FOR (FOREACH)

Facilidad en iteraciones sobre arrays y


colecciones que minimiza los errores de
sintaxis.

Bucle for antiguo:


void cancelAll(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
TimerTask tt = (TimerTask) i.next();
tt.cancel();
}
}
USO DEL NUEVO BUCLE FOR (FOREACH)

Nuevo bucle for:


void cancelAll(Collection c) {
for (Object o : c)
((TimerTask)o).cancel();
}

Podemos utilizar los genéricos para mejorar el


bucle:
void cancelAll(Collection<TimerTask> c) {
for (TimerTask task : c)
task.cancel();
}
USO DEL NUEVO BUCLE FOR
Estructuras compatibles con foreach
(FOREACH)

Para que una estructura de datos pueda ser


recorrida en foreach debe implementar la
interfaz Iterable.

Iterable devuelve un objeto java.util.Iterator


que posibilita recorrer los elementos de la
clase de forma establecida.
USO DEL NUEVO BUCLE FOR
Estructuras compatibles con foreach
(FOREACH)

Definición de ambas interfaces:


public interface Iterable<E> {
java.util.Iterator<E> iterator( );
}

public interface Iterator<E> {


boolean hasNext( );
E next( );
void remove( ); // Implementacion opcional
USO DEL NUEVO BUCLE FOR
Estructuras compatibles con foreach
(FOREACH)

Ejercicios:
 Definir
una estructura de datos de tipo pila que
pueda recorrerse mediante un bucle foreach
TIPOS DE RETORNO DE DATOS Y
PROMOCIÓN DIRECTA

En Java existe una serie de reglas para el retorno de valores en los métodos.

1. En un método que devuelve un objeto (de hecho, una referencia), se puede


devolver null.
public String metodo(){
return null;
}
2. Un array (o arreglo) es un tipo de retorno legal
public String[] metodo(){
return new String[] {“Madrid",“Londres",“NY"};
}
TIPOS DE RETORNO DE DATOS Y
PROMOCIÓN DIRECTA

3. Un método con tipo de retorno void ¡no devuelve nada!


public void inicializar(){
return;
}

4. En un método con un tipo de dato primitivo como retorno, se puede devolver


cualquier valor o variable que pueda ser implícitamente convertida hacia el tipo
de retorno declarado
public int Turno(){
char c = 'c';
return c; //devuelve un char convertido a int
}
TIPOS DE RETORNO DE DATOS Y
PROMOCIÓN DIRECTA

5. En un método con un tipo de dato primitivo como retorno, se puede devolver


cualquier valor o variable que pueda ser “casteada” hacia el tipo de retorno
declarado
public int Peso(){
float f = 79.5f;
return (int) f;
}
6. En un método con un objeto como tipo de retorno se puede devolver cualquier
tipo de objeto que pueda ser implícitamente convertido hacia el tipo de retorno
declarado (Covariant Returns)
public Figura getFigura(){
return new Triangulo; //Triangulo extends Figura
}
TIPOS DE RETORNO DE DATOS Y
PROMOCIÓN DIRECTA

Promoción directa (covariant returns): Ejemplo


class A { }
class B extends A { }
//Clases que demuestran la sobreescritura de métodos.
class C {
A getFoo() { return new A(); }
}
class D extends C {
B getFoo() { return new B(); }
}
4. Nuevos mecanismos de Java
OBJETIVOS DE LA UNIDAD

 Uso de assertions
 Uso de estructuras enum

 Uso de printf y format

 Expresiones regulares

 Uso de Split y Scanner

 Nuevas estructuras de Collections

 Uso del patrón Observer – Observable

 Nuevas estructuras RowSet


USO DE ASSERTIONS

Un assert es una condición que se debe dar en un programa para que no se


produzca un error.

Pueden suspender la ejecución de un programa pero no estamos obligados a


controlarla (declararlas y capturar su posible ejecución).

Mezcla de errores (problemas graves) y excepciones (controlables).

Útiles para evaluar pre y post condiciones


USO DE ASSERTIONS

Ejemplo: ejecutarlo: java –ea asserts.AssertSencillo


package asserts;

public class AssertSencillo {

public static void main(String [] main)


{
int i = 10;
assert i > 100 : “La variable está fuera del rango”;
System.out.println("Este es mi ejemplo");
}
}
USO DE ESTRUCTURAS ENUM

Nuevo tipo que se caracteriza por tener un número finito y normalmente


bajo de posibles valores.
Los enumerados implementan el concepto de constante, de uso frecuente
en programación, que hasta ahora se implementaba con variables static
final int. La formalización que proporcionan los tipos enumerados lleva
a otro nivel de seguridad y funcionalidad el uso de constantes en Java.
Definición:
modificadores enum NombreTipoEnumerado{ valor1,valor2,.. }
Ejemplo:
public enum NotasMusicales{ DO,RE,MI,FA,SOL,LA,SI }
USO DE ESTRUCTURAS
Características
ENUM

1. Las únicas instancias de un tipo enumerado son las que se crean en su


definición. Consecuencias:
 Los tipos enumerados no tienen constructor público.
 Las instancias no son clonables. No implementan la interfaz
Cloneable.
 Las instancias son inmutables.
 Es seguro comparar instancias con el comparador ==. El método
equals() está implementado con == y es final por lo que no puede ser
modificado.
2. Los enumerados son clases.
3. Implementan la interfaz Serializable y Comparable
USO DE ESTRUCTURAS ENUM
Nuevas estructuras de datos: EnumMap y EnumSet

EnumMap y EnumSet son implementaciones de las interfaces Map y Set que aprovechan la particularidad
de los tipos enumerados para conseguir más eficiencia y compactación.

EnumMap
EnumMap es una implementación de la interfaz Map donde el tipo de las claves del mapa es
un enumerado. La implementación aprovecha el conocimiento del número de valores
posibles del tipo enumerado, resultando muy rápida y compacta.
Ejemplo de creación:
Map<NotasMusicales,String> mapaNotas= new
EnumMap<NotasMusicales,String>(NotasMusicales.class);
USO DE ESTRUCTURAS ENUM
Nuevas estructuras de datos: EnumMap y EnumSet

EnumSet
EnumSet es una clase que implementa la interfaz Set donde el tipo de los elementos del
conjunto es un tipo enumerado. La implementación aprovecha el conocimiento sobre el
tipo enumerado, para representar internamente el conjunto como un vector de bits,
consiguiendo una gran eficiencia.
Además de implementar la interfaz Set, la clase define una larga serie de "constructores"
estáticos, que dan una gran flexibilidad a la hora de crear conjuntos.
Ejemplo de creación:
Set<NotasMusicales> conjNotas= EnumSet.allOf(NotasMusicales.class);
USO DE ESTRUCTURAS
Sintaxis avanzada
ENUM

La sintaxis de los tipos enumerados es más potente y compleja:


 Se pueden definir campos, métodos y constructores en un
tipo enumerado.
 Si se define uno o más constructores, es posible llamarlos
siguiendo los valores enumerados de los argumentos
correspondientes al constructor.
 Cada valor enumerado puede tener su propio cuerpo de clase
donde es posible sobrescribir métodos del tipo.
USO DE ESTRUCTURAS
Sintaxis avanzada: Ejemplo
ENUM

public enum Coin {


//Valores del enumerado. Pueden tener su propio cuerpo.
penny(1), nickel(5), dime(10), quarter(25);
//Propiedades
private final int value;
//Constructor
Coin(int value) { this.value = value; }
//Métodos
public int getValue() { return value; }
}
USO DE
Ejercicio
ESTRUCTURAS ENUM

Implementar un tipo enumerado FormatoAudio con los siguientes


formatos:
PCM, MP3 Y DOLBYDIGITAL.
Además se debe tener en cuenta:
- La enumeración debe permitir almacenar los canales (String) y el
bitrate (int).
- El tipo PCM no dispone de bitrate.
- Los métodos disponibles son:
- descripcion: Muestra la descripción del tipo
- reproducir(String cancion): Cada tipo debe tener su propia
forma de reproducción.
USO DE PRINTF Y FORMAT

Formatter
Se ha añadido un intérprete para el formateo de texto al estilo printf del lenguaje C.
La sintaxis es muy parecida aunque tiene algunas peculiaridades propias de
Java.
La clase principal es java.util.Formatter. Una interfaz muy relacionada es
Appendable.
Para hacer más sencilla la programación se ha dotado a clases como
java.io.PrintStream, java.io.PrintWriter, String, de los métodos:
format(String format, Object... args)
format(Locale l, String format, Object... args)
para acceder al formateo directamente, sin tener que crear un objeto
java.util.Formatter.
USO DE PRINTF Y FORMAT

Formatter
Sintaxis:
%[argument_index$][flags][width][.precision]conversion

- argument_index$: Entero. Indica la posición del argumento a utilizar (1$,2$...)


- flags: Conjunto de caracteres que modifican el formato de salida. Dependerá del tipo de
conversión (Date, Percentege, etc)
- width: Entero positivo. Indica el mínimo número de caracteres que se escribirán en la salida.
- precision: Entero positivo. Restringe el número máximo de caracteres
- conversion: Indica el contenido que se inserta en la salida.

Detalles del formato:


http://java.sun.com/javase/6/docs/api/java/util/Formatter.html#syntax
USO DE PRINTF Y FORMAT

Formatter
Ejemplo:
Fechas
Calendar c = new GregorianCalendar(1995, MAY, 23);
String s = String.format("Duke's Birthday: %1$tb %1$te,%1$tY", c);
// -> s == "Duke's Birthday: May 23, 1995"
System.out.println(s);
//Otra forma.
System.out.printf("Duke's Birthday2: %1$tb %1$te,%1$tY \n", c);
EXPRESIONES REGULARES

Java pone a disposición del programador


algunas clases que facilitan el manejo de
expresiones regulares:
- Pattern
- Matcher

La clase Pattern define el patrón, el cual después


mediante Matcher crearemos el objeto
encargado de indicar si un elemento pertenece a
nuestro lenguaje o no.
EXPRESIONES REGULARES

Una expresión regular es un patrón que describe a una cadena de caracteres.


Una expresión regular nos servirá para buscar un patrón en una cadena de texto.
Una expresión regular a parte de números y letras solo puede contener
< \$, ^, ., *, +, ?, [, ], \. >
Pattern (java.util.regex.Pattern )
En una expresión regular existe un patrón, el cual es el encargado de definir mediante
una determinada notación un lenguaje. La clase Pattern define ese patrón.

De la clase Pattern podemos resaltar:


 static Pattern compile (String expreg): Crea un patrón a partir de la expresión regular
dada por expreg.
EXPRESIONES REGULARES

Pattern (java.util.regex.Pattern )
 Matcher matcher(CharSequence input): Realizará el tratamiento del patrón sobre el texto que
se le pase como entrada.

 static boolean matches(String regex, CharSequence input): La utilidad de este método es que
permite la no utilización de un matcher para indicar si una expresión regular puede albergar
una cadena o parte de esta.

 String pattern(): Devuelve la expresión regular asociada al objeto Pattern sobre el que estemos
trabajando.

 String [] split (CharSequence input): Dado un patrón, crea un array de String con las diferentes
cadenas en las que se ha dividido.
EXPRESIONES REGULARES

Matcher (java.util.regex.Matcher)
Una vez definido el patrón con Pattern, tenemos
que crear un objeto que al recibir una cadena
de caracteres analice si dicha cadena, o las
subcadenas que la componen, pertenecen al
lenguaje dado.
EXPRESIONES REGULARES

Matcher (java.util.regex.Matcher)
 int end(int group)
Devuelve el índice del último carácter más 1 de la cadena que concuerda con la expresión regular.
 boolean find()
Busca en la cadena de texto a analizar a partir del último matching, la secuencia de caracteres que puede
concordar con la expresión regular.
 boolean find(int start)
Lo mismo que find() , pero empieza a buscar a partir de un índice que le es dado como parámetro.
 Pattern pattern()
Devuelve el Pattern sobre el que estamos trabajando.
 String replaceAll(Strip cad)
Devuelve una cadena que es la alteración de la cadena original a evaluar de forma que se han sustituido
todas subsecuencias de caracteres que coincidían con la expresión regular por la cadena “cad” pasada
por parámetro.
 int start()
El Matcher empieza a analizar en busca de una cadena de caracteres que concuerde con el patrón. (VER
EJEMPLOS)
USO DE SPLIT Y SCANNER

StringTokenizer
Existe desde la versión 1.0. Permite partir una cadena en tokens en función de un delimitador.

Constructores
StringTokenizer(String str)
StringTokenizer(String str, String delim)
StringTokenizer(String str, String delim, boolean returnDelims)

Métodos importantes
int countTokens();
boolean hasMoreElements();
boolean hasMoreTokens();
Object nextElement();
USO DE SPLIT Y SCANNER

Split
Método dentro de la clase String que divide
una cadena en función de una expresión
regular.
Si no encuentra concordancia con el patrón
devuelve un array con la misma cadena en su
primera posición.
Sintaxis:
USO DE SPLIT Y SCANNER

Split
String [] split(String regex,int limit)
limit: Controla el número de veces que se aplica el patrón a la cadena. Además afecta a la longitud
del array resultante.

Si limit > 0: El patrón se aplica como máximo n-1 veces. El array no será mayor de limit.
Si limit < 0: El patrón se aplica tantas veces como sea posible y no afecta a la longitud del array.
Si limit = 0: El patrón se aplica tantas veces como sea posible, no afecta a la longitud del array y,
además, se eliminan todas las cadenas vacías.

Veamos unos ejemplos


USO DE SPLIT Y SCANNER

Split
Ejemplo: cadena = “boo:and:foo”
Regex Limit Result
: 2 { "boo", "and:foo" }
: 5 { "boo", "and", "foo" }
: -2 { "boo", "and", "foo" }
o 5 { "b", "", ":and:f", "", "" }
o -2 { "b", "", ":and:f", "", "" }
o 0 { "b", "", ":and:f" }
USO DE SPLIT Y SCANNER

Scanner (java.util.Scanner)
Nueva clase de Java 5.0 que es capaz de
escanear un texto y extraer tipos primitivos o
Strings siguiendo una expresión regular como
delimitador.

Ver ejemplos de uso


COLLECTIONS

Interfaces
Fue introducido en la versión 1.2. Estas son las interfaces mas importantes:

Collection trabaja sobre conjuntos de elementos singulares


mientras que un Map trabaja sobre pares de valores.
http://java.sun.com/docs/books/tutorial/collections/index.html
COLLECTIONS

Interface Collection
Representa un conjunto de objetos de una manera generalizada. Esta interfaz define una serie de métodos que serán los que el
resto de interfaces, o clases que nosotros realicemos, deban implementar :
Métodos para agregar y eliminar elementos
boolean add(Object element)
boolean remove(Object element)
Métodos para realizar consultas
int size()
boolean isEmpty()
boolean contains(Object element)
Métodos para recorrer todos los elementos
Iterator iterator()
Métodos para realizar varias operaciones simultáneamente
boolean containsAll(Collection collection)
boolean addAll(Collection collection)
void clear()
void removeAll(Collection collection)
void retainAll(Collection collection)
COLLECTIONS

Interface List
Esta interfaz define un conjunto de datos ordenados permitiendo elementos duplicados.
Añade operaciones a nivel de índice de los elementos así como la posibilidad de
trabajar con una parte de la totalidad de la lista.
Métodos que nos permiten acceder a elementos por su posición :
void add(int index, Object element)
boolean addAll(int index, Collection collection)
Object get(int index)
int indexOf(Object object)
int lastIndexOf(Object object)
Object remove(int index)
Object set(int index, Object element)
COLLECTIONS

Interface List
También disponemos de métodos que nos permiten trabajar con una parte de la lista :
ListIterator listIterator()
ListIterator listIterator(int comiento)
List sublist(int inicio, int fin)

ListIterator extiende a Iterator permitiendo realizar recorridos bidireccionales (ver


ejemplo)
COLLECTIONS

Interface List
Dispone de 2 implementaciones:
- ArrayList: Representado mediante un array.
- LinkedList: Representado mediante una lista
doblemente enlazada.
COLLECTIONS

ArrayList
Sus características son:
- Sus métodos no son sincronizados (podremos sincronizarla a posteriori).
- Internamente implementa un array de 10 elementos por defecto.
Al aumentar el tamaño del array hay que redimensionarlo y mover todos los elementos a
partir de la posición donde vamos a insertar.
Estructura ideal si vamos a acceder a los elementos por su posición.
Optimización:
Insertar elementos siempre que sea posible al final de la lista.
COLLECTIONS

LinkedList
Sus características son:
- Sus métodos no son sincronizados (podremos sincronizarla a posteriori).
- Internamente implementa una lista enlazada:
1. Búsquedas mas costosas

2. Inserciones y borrados menos costosas que ArrayList. Evitamos mover


datos.

Estructura ideal si vamos a tener un gran número de inserciones y borrados.


COLLECTIONS

Interface Set
Representa un conjunto de datos en el más puro estilo matemático, es decir, no se
admiten duplicados. Por lo tanto si añadimos un elemento a un conjunto y ese
elemento ya se encontraba en su interior no se producirá ningún cambio en la
estructura de datos.

 Para determinar si un dato se encuentra o no en el conjunto, las implementaciones


que vienen en el API de Collections se basan en los métodos equals() y hashCode()
de la clase Object.
COLLECTIONS

Interface Set
Dispone de 2 implementaciones:
- HashSet: Representado mediante un HashMap.
- TreeSet: Representado mediante un TreeMap.
COLLECTIONS

HashSet
Implementa el conjunto de datos utilizando un tabla hash (HashMap).
Los elementos dentro de la interfaz no están ordenados y pueden variar su posición a lo
largo del tiempo a medida que se vayan haciendo operaciones de balanceo en la
estructura.

Importante: Si queremos añadirle objetos propios deberemos sobrescribir el metodo


hashCode() de los objetos ya que dos elementos son iguales si y solo si:
1. equals devuelve true
2. tienen el mismo hashCode.
(ver ejemplo: collections.hashSet.HashSetImprevisible y
collections.beans.MiObjeto)
COLLECTIONS

TreeSet
Esta implementación utiliza un TreeMap para almacenar los objetos. Los objetos se
guardan ordenados, en orden ascendente, según el orden natural de los objetos o
según el orden del comparador que le pasemos en el constructor.

Importante : Es muy importante que nuestro comparador sea consecuente con el


método equals() de los elementos que tengamos dentro del conjunto de datos. Esto
es debido a que aunque el funcionamiento de la estructura se basa en el método
equals el algoritmo de ordenación se basa en el método compareTo() de la interfaz
Comparator.
(ver ejemplo: collections.treeSet.MiTreeSet)
COLLECTIONS

Interface Map
Por definición, la interfaz define una estructura de datos que mapeará claves con valores sin permitir claves duplicadas. Tenemos
varios tipos de métodos :
Modificación
Object put(Object clave, Object valor)
void putAll(Map mapa)
void clear()
Object remove(Object clave)
Consulta
Object get(Object clave)
boolean containsKey(Object key)
boolean containsValue(Object value)
int size()
boolean isEmpty()
Vista
Set keySet()
Collection values()
Set entrySet()
COLLECTIONS

Interface Map
- Set keySet(): devuelve conjunto de datos (Set) con todas las claves
(únicas).
- Collection values(): devuelve conjunto de valores (no únicos)
- Set entrySet(): devuelve conjunto de elementos que implementan
interfaz Map.Entry que representa una pareja clave-valor. Podemos
modificar los valores mediante setValue().

(ver ejemplo: collections.map.RecorridoMap)


COLLECTIONS

Interface Map
Dispone de 2 implementaciones:
- HashMap: Representado mediante un HashMap
(sin ordenación). Permite “null” en clave y valores.
- TreeMap: Representado mediante un TreeMap
(ordenación natural o mediante comparador).
COLLECTIONS

HashMap
Implementa el conjunto de datos utilizando un tabla hash (HashMap).
Tiene dos parámetros que afectan a su rendimiento :
- capacidad inicial: Capacidad de la tabla cuando es creada(16 por defecto).
- factor de carga: porcentaje de tabla que puede estar lleno (75% por
defecto). Si se llega a este porcentaje se produce rehash
COLLECTIONS

TreeMap
La implementación de esta clase ordena los elementos por orden ascendente
de clave ya sea el orden natural de los objetos o el orden establecido por el
comparador que le pasemos en el constructor.

Al igual que en TreeSet el comparador ha de ser consistente con el método


equals().
COLLECTIONS

HashTable vs HashMap
HashTable es sincronizada mientras que HashMap no.

HashTable vs ConcurrentHashMap
Mismo tipo de estructura. ConcurrentHashMap no se bloquea en operaciones de
recuperación de datos.

Vector vs ArrayList
Vector es sincronizada mientras que ArrayList no.

En el resto de características son similares cada par.


COLLECTIONS

Algoritmos de ordenación
- Interface Comparable
Elementos de colección con orden determinado. Deberemos sobrescribir
el método:
public int compareTo(Object o)
- Clase Collator
Ordenación de caracteres
- Interfaz Comparator
Modificación de la clase Comparable o añadir ordenación a una clase que
no la posea. Sobrescribir métodos:
int compare(Object elemento1, Object elemento2)
boolean equals(Object o)
(Ver ejemplos paquete collections.ordenaciones)
COLLECTIONS

La clase Collections contiene métodos que permiten la creación de:

Colecciones inmutables
Colecciones inmutables a partir de otras que no lo son.
Collections.unmodifiableXXXXXX(XXXXX c)
Ej: List l = Collections.unmodifiableList(List l2);
Colecciones sincronizadas
Colecciones seguras ante hilos.
Collections.synchronizedXXXXX(XXXXX c);
Ej: List l = Collections.synchronizedList(List l);
donde XXXXX representa el tipo de estructura.
Ver ejemplos collections.modificablesYsynchronized
NUEVAS ESTRUCTURAS DE COLLECTIONS

RESUMEN
Una de las partes de la librería con más cambios:
• Tres de las nuevas características del lenguaje (genéricos, for-each y autoboxing) están muy
relacionadas con las colecciones.
• Tres nuevas interfaces: java.util.Queue, java.util.concurrent.BlockingQueue y
java.util.concurrent.ConcurrentMap y varias implementaciones de estas interfaces.
• Implementaciones de java.util.Map y java.util.Set específicas para el uso con tipos enumerados.
• Implementaciones de java.util.List y java.util.Set específicas para copy-on-write.
• Implementaciones wrapper para proporcionar seguridad de tipos dinámica a la mayoría de los
tipos.
• Métodos que implementan nuevos algoritmos para la manipulación de colecciones.
• Métodos para generar códigos hash y representaciones de texto de arrays.
NUEVAS ESTRUCTURAS ROWSET

 Los objetos RowSet, a diferencia de ResultSet, pueden operar sin la necesidad de mantener
abierta la conexión con la base de datos o data source.
 Existen cinco nuevas implementaciones de JDBC RowSet:
 JdbcRowSet: Para encapsular un ResultSet o un driver que utilice tecnología JDBC
 CachedRowSet: Contiene en memoria la colección de filas obtenidas de la base de datos y
puede, si fuera necesario, sincronizarse posteriormente en el tiempo.
 FilteredRowSet: Hereda de la anterior, y se utiliza para obtener un subconjunto de datos
 WebRowSet: Ademas puede escribir y leer RowSet en formato XML.
 JoinRowSet: Hereda de CachedRowSet y se emplea para unir múltiples objetos RowSet
USO DEL PATRÓN OBSERVER -
OBSERVABLE

El patrón Observer es utilizado cuando uno o más objetos (Observers) necesitan saber
sobre los cambios de estados u ocurrencia de eventos producidos en un objeto
Subject.

El modelo consiste en una clase Subject (java.util.Observable) con referencias a todos


los Observers (interface java.util.Observer), objetos interesados en el subject, y un
metodo notifyObservers() que invoca un metodo notify() implementado por cada uno
de los Observers.

De esta forma cuando el Subject sufre un cambio de estado o ante un evento avisa a
los Observers y mediante el callback de una funcion notify que implementa cada
Observer estos reaccionan al evento.
USO DEL PATRÓN OBSERVER -
OBSERVABLE
USO DEL PATRÓN OBSERVER -
OBSERVABLE

Ejemplo:
class Perro extends Observable {
private int edad;
public void cumplirAños() {
this.edad++;
setChanged();
this.notifyObservers();
// avisa a sus observadores sobre el cambio
// de estado del objeto o del evento ocurrido
}
}

class Observador implements Observer {


public void update(Observable perro, Object args) {
System.out.println("El perro cumplio años!");
}
}
En el programa que gestione ambos objetos al objeto Observable se le añadirá el Observer correspondiente.
Ejemplo: Imaginar observador JTextField que debe actualizarse de acuerdo a los cambios que sufre el modelo de datos
5. Uso de paquetes
OBJETIVOS DE LA UNIDAD

 Concepto de package
 Mecanismo para el diseño de aplicaciones

 Uso de archivos JAR

 Mejoras en despliegue: Utilización de Java Web


Start
 Mejoras en librerías, compilador en tiempo de
ejecución y JIT.
 Mejoras en Servicios Web
CONCEPTO DE PACKAGE

 Permiten organizar las clases de una manera


lógica.
 El nombre cualificado de una clase se
considera incluyendo su paquete (Ej:
com.at.MiClase)
 Un paquete puede contener otros paquetes.

 El nombre de los paquetes debe ser único


para cada clase, pudiendo darse problemas
USO DE ARCHIVOS JAR

Nuevas mejoras en archivos JAR en la versión Java 1.6:


- Cambios en el API: Dos nuevos streams de compresión han sido añadidos:
 java.util.zip.DeflaterInputStream: Lectura de datos comprimidos.
 java.util.zip.InflaterOutputStream: Escritura de datos comprimidos.
Muy útil si se quieren enviar datos a través de la red
 Mejoras en los ratios de compresión.

- Cambios en la implementación:
 En todas las plataformas: Los archivos zip pueden contener mas de 64k entradas.
 En windows:
 Soportados nombres de archivos mayores de 256 caracteres.
 Eliminada la limitación de abrir solo 2000 archivos zip símultáneamente (oh my god!!!)
http://download.java.net/jdk7/docs/technotes/tools/windows/jar.html
MECANISMOS PARA EL DISEÑO DE
APLICACIONES

Las aplicaciones diseñadas en Java deben tener un acoplamiento débil


entre módulos. Esto se consigue mediante diferentes patrones de
diseño:
- Uso de Interfaces
- Uso de Factorías estáticas y Patrón Singleton
- Uso del Patrón Comando (Command)

Otros conceptos avanzados que permiten el desacoplamiento son:


- Cross-cutting concern
- Programación Orientada a Aspectos
MEJORAS EN EL DESPLIEGUE
(DEPLOYMENT)

 Mejoras abundantes en Java Web Start. Muchas funcionalidades comunes de Java Web Start y Java
Plug-in se han unificado, y comparten panel de control: Java Control Panel.

 Mejoras en seguridad de acceso y control más flexible de la seguridad.

 Nuevo formato de compresión de ficheros jar, con mayor ratio de compresión, llamado Pack200.

 En Java Web Start:


 Eliminación del Developer Bundle. Ahora los recursos de JWS están integrados en el JRE y el JDK.
 Integración en el escritorio; se ha extendido al escritorio GNOME y se ha mejorado en general.
 Ahora un fichero JNLP puede solicitar cualquier argumento a la JVM. Hasta ahora los argumentos
que aceptaba eran limitados.
 Soporte completo a las Java Printing APIs.
UTILIZACIÓN JAVA WEB START

El software de Java Web Start permite


descargar y ejecutar aplicaciones Java desde
la Web. El software de Java Web Start:
 Permite activar las aplicaciones con un simple
clic.
 Garantiza que se está ejecutando la última
versión de la aplicación
 Elimina complejos procedimientos de instalación
o actualización
UTILIZACIÓN JAVA WEB START

Obtención del software de Java Web Start

El software de Java Web Start es un componente del entorno de ejecución de Java


(JRE) y se instala con el JRE.

Cuando se descarga por primera vez una aplicación que utiliza la tecnología Java Web
Start, el software de Java Web Start se ejecuta automáticamente y guarda la
aplicación localmente, en la memoria caché del equipo.

De este modo, las subsiguientes ejecuciones son prácticamente instantáneas, ya que


los recursos necesarios están disponibles de forma local.
UTILIZACIÓN JAVA WEB START

Ejecución de una aplicación con el software de Java Web Start

El software de Java Web Start ofrece tres métodos para ejecutar una aplicación:
 Desde un navegador Web

 Desde el administrador de aplicaciones incorporado.

 Desde un icono del escritorio y el menú Inicio (sólo en Microsoft Windows)

http://java.sun.com/javase/technologies/desktop/javawebstart/1.2/es/docs/Readme_es.html
http://java.sun.com/javase/technologies/desktop/javawebstart/1.2/es/docs/installguide_es.html
http://java.sun.com/javase/technologies/desktop/javawebstart/demos.html
MEJORAS EN LIBRERÍAS
JSR-013 Decimal Arithmetic

El paquete java.math contiene modificaciones:


- Adición en la clase BigDecimal de soporte para
cálculo en coma flotante de precisión fija.
- Clases como Math o StrictMath además
incluyen soporte para senos y cosenos
hiperbólicos, raíces cúbicas o logaritmos en
base 10.
- Soporte al uso de números hexadecimales con
MEJORAS EN
Java.util.Arrays
LIBRERÍAS

Esta clase compuesta por métodos estáticos


que facilitan el trabajo con arrays se ve
ampliada con nuevos métodos. Algunos son:
- toString(): Devuelve la representación del
array.
- deepToString(): Devuelve la representación
del array, soporta arrays multidimensionales.
- deepEquals(): Comparación de arrays
MEJORAS EN
java.util.Queue
LIBRERÍAS

Nueva interfaz genérica que modela la estructura


de cola, como colección de elementos en
espera a ser procesados. Forma parte del
framework Collections.

También se incorporan varias clases que


implementan la interfaz como
java.util.PriorityQueue,
MEJORAS EN LIBRERÍAS
Internacionalización (i18n)

La nueva versión de Java soporta Unicode 4.0, lo que hace insuficientes los 16
bits que se utilizaban hasta ahora para codificar caracteres. Algunos
caracteres, llamados caracteres suplementarios (suplementary characters),
que no son alcanzados por los 16 bits son representados con el tipo int.

Esto tiene bastantes implicaciones a nivel interno pero también en lo que


respecta a la interfaz de programación, clases como Character, String, el
paquete java.text se han visto afectadas.
MEJORAS
Networking
EN LIBRERÍAS

En cuanto a la programación de redes, hay


algunas novedades como la posibilidad de
establecer timeouts, la mejora en el manejo de
cookies, facilidades para comprobar el alcance
de un host, etc.

Ninguna realmente importante.


MEJORAS
Seguridad
EN LIBRERÍAS

J2SE 5.0 presenta notables mejoras en lo que a


seguridad respecta; soporta más estándares
(SASL, OCSP, TSP) , mejora el rendimiento y la
escalabilidad, mejoras en criptografía y Java
GSS, etc.
MEJORAS
Reflection
EN LIBRERÍAS

La mayoría de las mejoras tienen que ver con el soporte de todas las
novedades del lenguaje:
- Es posible saber si un tipo es genérico y todos los detalles al respecto.

- Obtención de información de los elementos anotados

- Determinar si un tipo es enumerado

- Determinar si un método tiene argumento variable, etc.

- Todo lo necesario relativo a las nuevas características del lenguaje.

- También se han añadido métodos para facilitar la programación y se ha


hecho genérico el tipo Class.
MEJORAS EN LIBRERÍAS
Java API for XML Processing (JAXP)

En J2SE 5.0 introduce una nueva versión JAXP 1.3 (en vez de JAXP 1.1 en J2SE 1.4) y
una nueva implementación de referencia basada en Apache Xerces (en vez de
Crimson en J2SE 1.4). Estos grandes cambios han traído algunas incompatibilidades
con las que hay que tener cuidado.
JAXP 1.3 mejora en varios aspectos la anterior versión, algunos son:
 Proporciona un validador para XML Schema.

 Posibilidad de usar otros esquemas de validación (paquete javax.xml.validation)

 Soporte de DOM Level 3

 Nueva API amigable para el uso de expresiones Xpath (paquete javax.xml.xpath)


Programación concurrente

MEJORAS EN LIBRERÍAS

SERIALIZACIÓN
Se ha añadido soporte a la serialización de tipos enumerados, que difiere de la del resto
objetos serializables por sus particularidades.
Mejoras en los paquetes java.util.concurrent, java.util.concurrent.atomic y
java.util.concurrent.locks.
Estas utilidades generan un entorno para el desarrollo de aplicaciones
concurrentes potente, escalable y extensible, gracias a colecciones síncronas,
semáforos, variables atómicas, etc..
También proporcionan primitivas de bajo nivel para programación concurrente
avanzada llegando a un grado sólo posible hasta ahora con programación
nativa.
La clase Thread también ha sido mejorada en varios aspectos.
MEJORAS EN LIBRERÍAS
Librerías de integración

RMI, JNDI, CORBA, Java IDL, y Java RMI-IIOP también han sido mejorados.
Respecto a JDBC, la interfaz javax.sql.RowSet ha sido implementada de las cinco
formas más comúnmente usada.
Swing
Por fin es posible en Swing sustituir jFrame.getContentPane().add() por
jFrame.add().
También se ha añadido soporte de impresión para JTable.
Por último se han incorporado dos nuevos look and feel: Synth y Ocean.
Java Management Extensions (JMX) 1.2
En J2SE 5.0 se incluye el soporte a JMX en la librería estándar, hasta
ahora era una librería independiente.
COMPILADOR EN TIEMPO DE EJECUCIÓN
(JIT)

 Al compilar una clase se genera el bytecode.


 Primeras versiones de Java siempre interpretaban bytecode.
 Rendimiento negativo
 La compilación en tiempo de ejecución (Just-in-time compilation) es una mejora
introducida en Java 1.3 que consiste en:

- La VM analiza rendimiento de los programas detectando “hot spot”


(porciones ejecutadas frecuente o repetidamente)

- Los hot spot son compilados para optimizar su ejecución.


COMPILADOR EN TIEMPO DE EJECUCIÓN
(JIT)

Con JIT el código es primero interpretado y posteriormente los “hot spot” son
compilados al vuelo
 Necesario ejecutar los programas varias veces antes de medir
rendimientos.

El proceso de compilación JIT utiliza algunas técnicas de optimización (Inline


expansion, Loop unwinding, Bounds-checking elimination) y técnicas de
asignación de registros en función de la arquitectura hardware disponible.
MEJORAS EN SERVICIOS WEB

Se incluye la pila de servicios web con nuevas mejoras como parte del API
JDK:

JSR 222: JAXB 2.0


JSR 224: JAX-RPC 2.0
JSR 173: STAX (Streaming API for XML)
JSR 181: Web Services Metadata (Anotaciones)

Mejoras generales en publicación y tratamiento de los web services.


6. Gestión de Excepciones
OBJETIVOS DE LA UNIDAD

 Consideraciones generales
 Mecanismo de lanzamiento de throws

 Buenas prácticas en la gestión de excepciones

 Uso correcto de la gestión de excepciones

 Reglas en la sobreescritura de métodos con


respecto a las excepciones.
CONSIDERACIONES GENERALES
Tipos de Excepciones
CONSIDERACIONES GENERALES
Tipos de Excepciones

- Checked: Excepciones que son obligatorias su captura o


lanzamiento a un nivel superior. Indican un problema esperado.
Deben capturarse (try-catch) o escalarlas a un nivel superior
mediante cláusula throws en métodos.
Todas las que heredan de Exception.
- Unchecked: Excepciones que no son obligatorias su captura.
Indican un problema inesperado.
Todas las que heredan de RuntimeException
- Errors: Problemas serios que casi siempre indican una no
recuperación del sistema (OutOfMemory, StackOverFlow…)
CONSIDERACIONES GENERALES
Mecanismos de lanzamiento

Una excepción es lanzada mediante la sentencia throw.


Ej: throw new MyServiceException("Blah", e);

Las excepciones puede capturarse o lanzarse a niveles superiores


public void foo() throws IOException {
….
}
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Podemos dividir las buenas prácticas en:


- Buenas prácticas en el uso de excepciones
- Buenas prácticas en el diseño de excepciones
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Buenas prácticas en el uso de excepciones


A continuación se explican los principales fallos a la hora de utilizar las excepciones. Lo que se conoce
como Antipatrones (Antipatterns):
- Log and throw
- Throwing Exception
- Throwing the kitchen sink
- Catching Exception
- Destructive Wrapping
- Log and return null
- Catch and ignore
- Throw from within Finally
- Multi-line log messages
- Unsupported Operation Returning null
- Ignoring InterruptedException
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Log and Throw


Ejemplo:
catch (NoSuchMethodException e) {
e.printStackTrace();
throw new MyServiceException("Blah", e);
}
Problema: Múltiples mensajes en el log para un único problema.

Solución: O lanzar la excepción o imprimir traza pero nunca ambas.


BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Throwing Exception


Ejemplo:
public void foo() throws Exception {

Problema: Uso inapropiado de “checked exception”. Algo puede ir mal pero


sin especificar demasiado el que.

Solución: Declarar las excepciones específicas que el método pueda lanzar


BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Throwing the kitchen sink


Ejemplo:
public void foo() throws MyException,
AnotherException, SomeOtherException,
YetAnotherException
{
Problema: Lanzar múltiples excepciones en un método no tiene que ser un
problema pero si las excepciones tiene un significado similar podemos mejorar
nuestro método.

Solución: Crear una excepción que agrupe a todas ellas.


BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Catching Exception


Ejemplo:
try {
foo();
} catch (Exception e) {
LOG.error("Foo failed", e);
}
Problema: Captura de la excepción genérica. Si el método capturado añade nuevas
excepciones a la firma de su método el desarrollador debería tenerlo en cuenta y
capturar esta específica excepción. De esta forma no se entera del cambio y su
código es susceptible de fallo.

Solución: Capturar excepciones específicas que se lancen en los métodos


BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Destructive wrapping


Ejemplo:
catch (NoSuchMethodException e) {
throw new MyServiceException("Blah: "
,e.getMessage());
}
Problema: Destrucción de las trazas de la pila
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Log and return null


Ejemplo:
catch (NoSuchMethodException e) {
e.printStackTrace();
return null;
}
Problema: Es correcto si el método de forma normal puede lanzar null. Por ejemplo,
método devuelve null si la cadena de búsqueda no fue encontrada.

Solución: Lanzar la excepción en lugar de devolver null.


BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Catch and ignore


Ejemplo:
catch (NoSuchMethodException e) {
return null;
}
Problema: Pérdida para siempre de la información que produce el lanzar la
excepción.

Solución: Capturar la excepción o re-lanzarla otra vez.


BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Throw from within finally


Ejemplo:
try {
blah();
} finally {
cleanUp(); //Método que puede lanzar una excepción
}
Problema: El problema existe si cleanUp() es susceptible de lanzar una excepción, ya
que si blah() lanza una excepción y posteriormente cleanUp() lanza otra se perderá la
primera excepción.

Solución: Asegurarnos de capturar o imprimir traza. Nunca elevar la excepción producida


en el finally sin mas.
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Multi-line log messages


Ejemplo:
Log.debug(“Estableciendo política de cacheo A”);
Log.debug(“Estableciendo política de cacheo B”);

Problema: En una aplicación en la que 500 hilos simultáneamente intentan escribir en


el log puede que las 2 trazas aparezcan con una separación de 1000 líneas.

Solución: Intentar agrupar los mensajes de log. Log.debug(“Estableciendo política de


cacheo A – Estableciendo política de cacheo B”);
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Unsupported operation returning null


Ejemplo:
public String foo() {
// Not supported in this implementation.
return null;
}
Problema: Es correcto si tratamos de diseñar una clase con diferentes métodos que implementen
las subclases opcionalmente. Si este no es el caso queda confuso que el método foo()
devuelva null sin sentido.

Solución: Si nuestro método no es un método descrito anteriormente debería lanzarse una


UnsupportedOperationException.
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Antipatrones: Ignoring InterruptedException


Ejemplo:
while (true) {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {}
doSomethingCool();
}
Problema: La excepción es una pista de que el hilo puede terminar por determinadas
circunstancias. De esta forma no se está realizando un tratamiento correcto del error.

Solución: Finalizar el hilo con break dentro del catch.


BUENAS PRÁCTICAS EN LA GESTIÓN
DE EXCEPCIONES

En resumen unas buenas prácticas en el uso de excepciones:


1. Siempre liberar recursos en bloque finally. Por ejemplo, cierre de conexión con
base de datos.
2. No usar excepciones para controlar el flujo de los programas

public void useExceptionsForFlowControl() { public void increaseCount()


try { throws MaximumCountReachedException {
while (true) { if (count >= 5000)
increaseCount(); throw new
} MaximumCountReachedException();
} catch (MaximumCountReachedException ex{ }
}
//continua la ejecución
}
BUENAS PRÁCTICAS EN LA GESTIÓN
DE EXCEPCIONES

3. No suprimir o ignorar excepciones


Si un método lanza una excepción debemos tenerlo en cuenta. Si no consideramos necesaria su
captura podemos convertir la excepción “checked” en “unchecked” pero nunca ignorarla.

4. No capturar excepciones de mas alto grado (Throwable, Exception, Error)


Al capturar excepciones mediante Exception estamos incluyendo también las RuntimeException
(unchecked).

5. Escribir en archivos de log solo una vez al capturar una excepción.


BUENAS PRÁCTICAS EN LA GESTIÓN
DE EXCEPCIONES

6. Lanzar excepciones lo mas específicas posibles


Exception
IOException
FileNotFoundException
EOFException
ObjectStreamException
Utilizar múltiples bloques catch si fuera necesario.

7. Throw Early.
Lanzar excepciones en cuanto se produzcan las condiciones necesarias.
Ejemplo:
public void readPreferences(String filename)
throws IllegalArgumentException {
if (filename == null){
throw new IllegalArgumentException("filename is null");
} //if

8. Catch Late
Capturar excepciones en las capas mas propicias para ello, donde el programa pueda recuperarse de la excepción u poder informar al usuario
de las causas.
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Buenas prácticas en el diseño de excepciones


A la hora de diseñar un API que lance
excepciones debemos tener en cuenta:
- Utilizar excepciones “checked” o “unchecked”
- Preservar la encapsulación
- Precaución en la creación de excepciones
personalizadas
- Documentar excepciones
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Buenas prácticas en el diseño de excepciones


- Utilizar excepciones “checked” o “unchecked”
Si el programa puede recuperarse razonablemente de
una excepción  checked

Si el programa no puede hacer nada para recuperarse


de la excepción  unchecked
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Buenas prácticas en el diseño de excepciones


- Preservar la encapsulación

Intentar no escalar a otras capas las excepciones específicas


producidas en otra.
Ejemplo: SQLException producida en DAO. Intentar no escalarla a la
capa de negocio ya que esta no debe saber su existencia. Opciones:
- Convertir SQLException en otra excepción “checked” (la
aplicación se puede recuperar del fallo)
- Convertir SQLException en excepción “unchecked” (si no
se puede hacer nada al respecto)
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Buenas prácticas en el diseño de excepciones


- Precaución en la creación de excepciones personalizadas
Intentar no crear (siempre que sea posible) nuevas excepciones personalizadas que no aporten información
útil al código. Un ejemplo:
No aporta info:
public class DuplicateUsernameException extends Exception {}
Aporta info:
public class DuplicateUsernameException
extends Exception {
public DuplicateUsernameException
(String username){....}
public String requestedUsername(){...}
public String[] availableNames(){...}
}
BUENAS PRÁCTICAS EN LA GESTIÓN DE
EXCEPCIONES

Buenas prácticas en el diseño de excepciones


- Documentar excepciones
Mediante:
1. @throws en el javadoc. Tanto para
checked y unchecked excepciones.
2. Realizando casos de prueba (JUnit) en los
que se plasme el uso de las excepciones.
REGLAS EN LA SOBREESCRITURA DE
MÉTODOS

En Java Language Specification se comenta:


8.4.6.3 Requirements in Overriding and Hiding
“If a method declaration overrides or hides the declaration of another method, then a compile-
time error occurs if they have different return types or if one has a return type and the other is
void. Moreover, a method declaration must not have a throws clause that conflicts (§8.4.4)
with that of any method that it overrides or hides; otherwise, a compile-time error occurs.”

Por tanto, la sobreescritura de métodos no obliga a indicar las excepciones lanzadas por un
método en la SuperClase de otra dada.

http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#227965
7. Multithreading
OBJETIVOS DE LA UNIDAD

 Arquitectura de los Threads


 Modificaciones en los Threads en versión 5

 Establecer grupos y prioridades

 Comunicación inter-threads.

 Uso de synchronized

 Nuevas clases en el uso de Threads

 Java Realtime
ARQUITECTURA DE LOS THREADS

Definición
Unidad de ejecución de un proceso y está asociado con una secuencia de
instrucciones, un conjunto de registros y una pila.

Cada hilo se ejecuta de manera independiente (propio PC, registros y pila) pero
comparten espacio de direcciones  compartir variables globales, ficheros
abiertos, elementos de sincronización, etc.

Cada hilo se ejecuta con una determinada prioridad ejecutándose antes lo de mayor
prioridad (setPriority()).

Hilos puede ser demonios (setDaemon()).


ARQUITECTURA DE LOS THREADS

Estados de un hilo
- Nuevo: Hilo creado pero no activado. Cuando se active pasará al estado
preparado.
- Preparado: Hilo activo a la espera de asignación de CPU.
- En ejecución: Hilo activo y con CPU asignada.
- Bloqueado: Hilo espera que otro elimine el bloqueo
 Dormido: Hilo bloqueado durante una cantidad de tiempo determinada
después del cual despierta y pasa a preparado.
 Esperando: Esperando que ocurra (condición, operación E/S. Cuando
ocurra pasa al estado preparado.
- Muerto: Hilo finalizado pero no ha sido recogido por su padre
ARQUITECTURA DE LOS THREADS

Programación con hilos


- Clase Thread: Proporciona la mayoría de soporte
a hilos.
- Clase Object:
- Interfaz Runnable
- Interfaz Thread.UncaughtExceptionHandler
- Clase ThreadGroup
MODIFICACIONES EN LOS THREADS

En Java 1.5 se ha producido las siguientes mejoras en la clase java.lang.Thread:


- Prioridad de los hilos ha cambiado igualándose a los hilos nativos.
- Enumeración Thread.State y API getState() proporcionan utilidades para conocer el estado de
un hilo.
- Métodos para conocer las trazas de la pila (stack trace) de uno o varios hilos: getStackTrace() y
getAllStackTrace().
- UncaughtExceptionHandler ahora disponible en clase Thread (anteriormente a través de
ThreadGroup)
- Nuevo forma de dormir hilos tiempos inferiores a 1 milisegundo  sleep();
http://java.sun.com/j2se/1.5.0/docs/relnotes/features.html#concurrency
ESTABLECER GRUPOS Y PRIORIDADES

Grupos
Cada hilo Java es miembro de un grupo de hilos. Puede ser el predefinido por la
JVM o uno especificado explícitamente.

Los grupos proporcionan un mecanismo para agrupar varios hilos en un único


objeto  manipulación simultánea de todos (interrumpir grupo invocando
interrupt).

Un grupo de hilos puede pertenecer a otro grupo (ESTRUCTURA EN ÁRBOL).

Un hilo solo tiene acceso a la información de su grupo


ESTABLECER GRUPOS Y PRIORIDADES

Grupos
Tipos de grupos
- Predefinidos
Creación de un hilo sin especificar su grupo, la JVM lo coloca en el mismo
grupo del hijo bajo el cual se crea.

Para obtener grupo actual de un hilo: Thread.currentThread().getThreadGroup()


- Explícito
Añadir un hilo a un determinado grupo. Primero deberemos crear el grupo.
Después añadir el hilo al grupo por medio de un constructor.
ESTABLECER GRUPOS Y PRIORIDADES

Grupos
Tipos de grupos
- Explícito
Ejemplo:
1.-Crear el grupo
ThreadGroup consumidores = new ThreadGroup(“consumidores”);
2.- Llamada a constructor dentro del hilo
public class Consumidor extends Thread{
private Mensaje msg;
public Consumidor(Mensaje msj, ThreadGroup grupo, String nombre){
super(grupo,nombre);
msg = msj;
}
public void run(){
//..
}
}
ESTABLECER GRUPOS Y PRIORIDADES

Prioridades
Cada hilo Java tiene una prioridad (1 a 10).
Constantes
Dentro de la clase Thread
MIN_PRIORITY = 1 NORM_PRIORITY = 5 MAX_PRIORITY = 10

Por defecto NORM_PRIORITY.


Para cambiar la del hilo actual prioridad mediante
setPriority(int prioridad);

Hilos con la misma prioridad permanecen en cola circular (algoritmo Round Robin). El
sistema asigna un cuanto de tiempo para la ejecución de los hilos
COMUNICACIÓN INTER-THREADS

Los hilos pueden comunicarse mediante:


- Variables y objetos globales (públicas)
- Recursos en disco
- Dispositivos externos
- Tuberías (PIPES).
COMUNICACIÓN INTER-THREADS

Tuberías
Canalizan la entrada de un hilo en la salida de otro. De esta forma 2 hilos pueden compartir datos.

Las clases son las siguientes:


- PipedReader (caracteres) y PipedInputStream (bytes) : Lectura de tuberías
- PipedWriter (caracteres) y PipedOutputStream (bytes): Escritura en tuberías.

Uso:
PipedWriter emisor = new PipedWriter();
PipedReader receptor = new PipedReader(emisor);

Creación del flujo:


//Escritura
PrintWriter pw = new PrintWriter(emisor);
pw.println(“…”);
//Lectura
BufferedReader br = new BufferedReader(receptor);
br.readLine();
USO DE SYNCHRONIZED

Exclusión mutua
Garantizar que solo 1 hilo simultáneamente ejecuta la sección crítica (área con objetos comunes a
sincronizar).

En Java, cada objeto tiene un monitor (lock) que es controlado por un solo hilo simultáneamente.

El hilo al hacerse cargo del monitor bloquea el acceso por otro hilo. Cuando libera el monitor libera
el bloqueo.

Java implementa los monitores reentrantes: JVM permite tomar el control de un monitor a un hilo
que ya posee ese monitor (Ejemplo: Llamada a 2 métodos synchronized)

Implementación de sección crítica mediante synchronized


USO DE SYNCHRONIZED

Synchronized
Podemos realizar la sincronización de 2 formas:
void m() {
synchronized(this) {
// ...
}
}

synchronized void m() {


// ...
}
OTRAS FORMAS DE SINCRONIZAR

Synchronized permite sincronización de hilos involucrados en una misma tarea.


Si los hilos realizan diferentes tareas utilizaremos wait, notify y notifyAll.
- wait: Envía al hilo actualmente en ejecución al estado de espera hasta que
otro hilo invoque notify, notifyAll o interrupt
- notify: Despierta un hilo de los que estén esperando adquirir el monitor
- notifyAll: Despierta todos los hilos que estén esperando. Estos hilos
competirán por la ejecución de la CPU.
NUEVAS CLASES EN EL USO DE THREADS

Paquete java.util.concurrent incorporado en JDK 1.5 que incluye:


- Semaphore: Restringe el acceso a los recursos.
- ConcurrentHashMap, ConcurrentLinkedQueue, ConcurrentSkiptListMap
que permiten modificación concurrente de sus datos.
- Executor: Permite ejecutar clases Runnable sin tener que invocar a su
método start() directamente.
NUEVAS CLASES EN EL USO DE THREADS

Executor
-Ejecución de threads.
Antes:
new Thread(new(RunnableTask())).start() ;
Ahora:
Executor executor = anExecutor;
executor.execute(new RunnableTask1());
executor.execute(new RunnableTask2());
- Ejecución de tareas
class ThreadPerTaskExecutor implements Executor {
public void execute(Runnable r) {
new Thread(r).start();
}
}
JAVA REAL TIME

Ejecución en tiempo real.


Definición de Sun:
El entorno de programación debe proveer las abstracciones necesarias para permitir a
los desarrolladores manipular correctamente el comportamiento temporal de la
lógica de la aplicación. No es necesariamente rápida, pequeña, o de uso exclusivo
para el control industrial; todo es acerca de la predecibilidad de la ejecución de la
lógica de la aplicación respecto al tiempo.

Objetivo
Poder organizar a todas las tareas de tal manera que completen su trabajo antes de sus
metas de tiempo.
JAVA REAL TIME

Tipos de sistemas en tiempo real


- Tiempo real inflexible: El sistema debe cumplir todas sus metas de tiempos sin
excepción. Respuestas muy pequeñas. Sistemas de seguridad crítica.

Actualmente está siendo estudiada en JSR-302 y no forma parte de RTSJ (Real-Time


Specification for Java)
- Tiempo real flexible: Es aquel que funcionará correctamente, de acuerdo a su
especificación, aunque el sistema ocasionalmente no cumpla con las metas de
tiempo. Ej: Red telefónica celular
JAVA REAL TIME

Lo Impredecible de las aplicaciones Java


 Gestión del sistema operativo. En la tecnología Java, los threads son
creados por la JVM pero, en última instancia, son gestionados por el sistema
operativo.
 Inversión de prioridades. Un hilo de menor prioridad compartiendo un
recurso con hilo de mayor prioridad (monitor) puede bloquear al hilo de
mayor prioridad.
 Carga de clases, inicialización y compilación. La carga de clases es
perezosa (cuando son necesarias). Su inicialización también puede serlo. La
JVM solo compila clases que considera necesarias por su alta ejecución (JIT)
 Garbage Collector. Detener todos los threads para que actúe 
Impredecible.
JAVA REAL TIME

La especificación
 La Especificación de Tiempo Real para Java (RTSJ), o JSR 1, especifica cómo un sistema Java
debería comportarse en un contexto de tiempo real. La especificación fue desarrollada durante
varios años por expertos de Java y de aplicaciones en tiempo real.
 La RTSJ está diseñada para extender la familia Java (toda la plataforma Java, Java SE, Java EE,
Java Micro Edition y demás), y tiene el requerimiento de que cualquier implementación debe
pasar el Test de Compatibilidad JSR 1 (TCK) y el TCK propio de la plataforma en la cual está
basada. Es decir RTSJ extiende naturalmente cualquiera de las plataformas Java existentes.
 RTSJ introduce varias características nuevas para soportar operaciones en tiempo real. Estas
características incluyen nuevos tipos de thread, nuevos modelos de gestión de memoria, y
otros frameworks también nuevos.
JAVA REAL TIME

- Heap estándar. Con GC


- Memoria inmortal. Sin GC. Los objetos nunca se eliminan.
- Memoria acotada. Sin GC. Los objetos se eliminan una vez el hilo ha
finalizado. Reserva de memoria al comienzo de la tarea.
Ventajas
- Reserva predecible y liberación predecible
- Reserva no fallará
Desventajas
- No se pueden guardar referencias de objetos de la memoria acotada
JAVA REAL TIME

Enlaces
- http://java.sun.com/developer/technicalArticles/Programming/rt_pt1/
- http://java.sun.com/developer/technicalArticles/Programming/rt_pt2/index.html
- http://javolution.org/
8. Garbage Collector
OBJETIVOS DE LA UNIDAD

 Arquitectura de la JVM
 HotSpots (tipos, características, mejoras)

 Uso de visualgc

 Visualizar el comportamiento del GC

 Consideraciones sobre finalize(), Runtime.gc() y


System.gc().
 Buenas prácticas en el uso del GC
HOTSPOT
Tipos

 Java HotSpot™ Client VM (client VM).


 En plataformas utilizadas típicamente para
aplicaciones cliente.
 VM modificada para reducir el tiempo de
arranque y memoria utilizada
 Java HotSpot Server VM (server VM).
 Presente en todas las plataformas.
HOTSPOT

Características comunes a ambas implementaciones


 Compilador Adaptativo (Adaptive compiler)

 Aplicaciones lanzadas utilizando un interprete estándar. Posteriormente


analiza la ejecución del código para detectar cuellos de botella o hot
spot que compilará para aumentar el rendimiento evitando la
compilación de código poco utilizado.
 Decide “al vuelo” la mejor forma de optimizar el código compilado con
técnicas como el in-lining.
 Asignación de memoria y garbage collector más rápidos.

 Sincronización de hilos

 Presente en todas las plataformas.


HOTSPOT

Ergonomía (Ergonomics)
Las mejoras presentes en la versión J2SE 1.5 (Ergonomía) tratan de
proporcionar un buen rendimiento para la JVM con una mínima utilización
de las opciones (en línea de comandos).

La ergonomía de la JVM trata de ajustar la mejor selección de:


- Garbage Collector: Dentro de entre todos los disponibles
- Tamaño de la memoria Heap: Tamaño mínimo, tamaño máximo, etc.
- Compilador en tiempo de ejecución (JIT)
COMPORTAMIENTO DEL GC

A la izquierda los objetos young que se eliminan rápidamente. A la derecha los


que sobreviven durante mas tiempo
COMPORTAMIENTO DEL GC: ÁREAS DE
MEMORIA (HEAP)

Podemos dividir la memoria del Heap en las siguientes regiones:


- Zona Young: Formada por zona Edén y zonas Survivor.
Los objetos son inicialmente colocados en la zona Edén. Una zona Survivor está
siempre vacía sirviendo de destino la siguiente vez entre la zona Edén y la zona
Survivor utilizada.
- Zona Tenured (old): Los objetos son copiados en la zona Young hasta que pasan
a tener una edad y son copiados a la esta zona.
- Zona Perm: Contiene datos requeridos por la VM que no tienen equivalencia en
Java. Almacena descripción de clases, métodos, etc.
COMPORTAMIENTO DEL GC: ÁREAS DE
MEMORIA (HEAP)
COMPORTAMIENTO DEL GC: ÁREAS DE
MEMORIA (HEAP)

En cada recolección el GC intenta mantener las zonas de memoria dentro


de unos límites:
-XX:MinHeapFreeRatio = 40: Mínimo porcentaje de memoria (heap) libre
después de un GC para evitar expansión.
–XX:MaxHeapFreeRatio = 70 : Máximo porcentaje de memoria (heap) libre
después de un GC para evitar encogimiento.
-Xms : Tamaño inicial (defecto 3670k)
-Xmx: Tamaño máximo de la memoria (defecto 64m)

En servidores estos parámetros son insuficientes


TIPOS DE GC

Además del GC en serie a partir de la versión 1.5 existen los siguientes GC:

 Throughput collector: Es paralelo y actúa sobre la zona Young. –


XX:+UseParallelGC
 Concurrent Mark Sweep (Recolector de pausa baja): Es paralelo. Utilizado
para recolectar la zona tenured y realiza la mayor parte de la recolección
concurrentemente durante la ejecución de las aplicaciones. –
XX:+useConcMarkSweepGC
 Incremental (train) Low Pauses: -XX:+UseTrainGC. No ha cambiado desde la
versión 1.4.2.
HOTSPOTS
Mejoras en JDK 5.0: Configuración

Class Data Sharing


- Reconstrucción del archivo compartido
java -Xshare:dump
- Control Manual
-Xshare:off :Deshabilita class data sharing.
-Xshare:on :Obliga el class data sharing a habilitarse. Podría no habilitarse por varios
motivos.
-Xshare:auto : Por defecto, habilita la opción siempre que sea posible.

Server-Class Machine Detection


Opción automática
HOTSPOTS
Mejoras en JDK 5.0: Configuración

Garbage Collector Ergonomics:


1.PararellGC: En VM Server el GC ha cambiado de recolección en serie a recolección en paralelo( -
XX:+UsePararellGC)
2.En VM Server con PararellGC el tamaño del heap ha cambiado:
a)Tamaño inicial (mayor de 1/64).
-Xms
b)Tamaño máximo(menor de ¼ o 1GB)
-Xmx
3.PararellGC lanza una excepción(out-of-memory) si se gasta mucho tiempo en recolectar una porción
pequeña del heap. Para evitarlo podemos incrementar el tamaño del heap. Además de establecer unos
parámetros (ver parametros)
4. Cambios en -XX:+UseAdaptiveSizePolicy al usar PararellGC.

http://download.java.net/jdk7/docs/technotes/guides/vm/gc-ergonomics.html
CAMBIOS EN JAVA VIRTUAL MACHINE
Mejoras en JDK 6.0

Mejoras en el Garbage Collector


- Concurrent Mark Sweep Collector Enhancement (Concurrent Low Pause Collector)
Conocido como recolector paralelo de pausa baja o CMS. Está destinado a aplicaciones que son sensibles a
pausas prolongadas provocadas por el GC potenciando la actividad del GC concurrentemente. Utilizado en
máquinas con múltiples procesadores.
Uso: -XX:+UseConcMarkSweepGC
Beneficios
- El objetivo del CMS es reducir estos tiempos en pausas mas cortas.
- Aumento del tamaño de “young generation” cuando el CMS es usado (4MB a 16MB)
- Marcado paralelo de objetos no usado (Full GC). En versiones anteriores todo se realizaba en un solo
hilo.
HOTSPOTS
Opciones

Resto de opciones consultar :


http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp
USO DE VISUALGC

VisualGC es una herramienta que permite


visualizar gráficamente el Heap de una
JVM 1.4 ó 1.5, sus distintas zonas y el
grado de ocupación de cada una.

http://salzotech.blogspot.com/2007/08/visualgc-con-
jvmstat.html
CONSIDERACIONES SOBRE FINALIZE()

Método que se ejecuta en un objeto previamente a que el Garbage Collector


libere la memoria ocupada dicho objeto.

Los objetos con método finalize() sobreescrito tienen un rendimiento


menor.

No deben realizarse acciones en finalize() vitales para el sistema como


liberación de recursos, cierre de conexiones con base de datos, etc ya
que podría nunca llamarse a este método si el GC nunca liberase el
objeto asociado.
CONSIDERACIONES SOBRE RUNTIME.GC Y
SYSTEM.GC

 Ambos métodos son equivalentes. Sugieren a la VM que ejecute el


proceso de GC que liberará los objetos marcados como liberables.

 Es importante tener en cuenta que estos métodos no nos aseguran


que se vaya a ejecutar el GC y podría suceder que este nunca se
ejecutase porque la VM así lo considerase.
 Sugiere una recolección total de objetos (full GC)
 Se puede deshabilitar la llamada expresamente al GC mediante la
opción -XX:+DisableExplicitGC
BUENAS PRÁCTICAS EN EL USO DEL GC

- No llamar expresamente al GC al menos que sea estrictamente necesario.


Impacto en el rendimiento al realizar “full GC”.

- Ejecutar los programas en versión Java 6  aumento del rendimiento y


mejora con GC en paralelo.

- Minimizar el uso de objetos con método finalize().

- Nulling: Hacer null todos los objetos que no se utilicen ayuda a su


eliminación por parte del GC. Especialmente indicado en trabajo con arrays.
BUENAS PRÁCTICAS EN EL USO DEL GC

Nulling Con Arrays:


public class SimpleBoundedStack {
private static final int MAXLEN = 100;
private Object stack[] = new Object[MAXLEN];
private int top = -1; La referencia almacenada
en stack[top+1] no será
public void push(Object p) {
alcanzable por el
stack [++top] = p; programa en mucho
} tiempo pero sigue siendo
public Object pop() { considerada alcanzable
Object p = stack [top]; por el GC y, por tanto, no
eliminada.
stack [top--] = null; // null explícito
return p;
}
9. API de Entrada / Salida
OBJETIVOS DE LA UNIDAD

 Uso del nuevo paquete java.nio


 Concepto de stream

 La clase File y sus características.

 Clases de entrada/salida

 Clases Buffer complementarias

 Lectura y escritura de archivos.


CONCEPTO DE STREAM

Objeto que hace de intermediario entre el origen


de los datos y el programa. De esta forma, el
programa leerá o escribirá en el flujo sin
importarle desde dónde viene la información o
adonde va.

Existen flujos de entrada (inputStream) y flujos


de salida (outputStream)
CONCEPTO DE STREAM

 Si usamos sólo FileInputStream, FileOuputStream, FileReader o FileWriter, cada vez que


hagamos una lectura o escritura, se hará fisicamente en el disco duro. Si escribimos o leemos
pocos caracteres cada vez, el proceso se hace costoso y lento, con muchos accesos a disco
duro.
 Los BufferedReader, BufferedInputStream, BufferedWriter y BufferedOutputStream añaden un
buffer intermedio. Cuando leamos o escribamos, esta clase controlará los accesos a disco.
 Si vamos escribiendo, se guardará los datos hasta que tenga bastantes datos como para hacer
la escritura eficiente.
 Si queremos leer, la clase leerá muchos datos de golpe, aunque sólo nos dé los que hayamos
pedido. En las siguientes lecturas nos dará lo que tiene almacenado, hasta que necesite leer
otra vez.
 Esta forma de trabajar hace los accesos a disco más eficientes y el programa correrá más
rápido. La diferencia se notará más cuanto mayor sea el fichero que queremos leer o escribir.
USO DE PAQUETE JAVA.NIO

Aportada en la versión Java 1.4.


La nueva API puede dividirse en tres grandes paquetes:
- java.nio: Define Buffers, que se usan para almacenar secuencias de
bytes o de otros valores primitivos (int, float, char, double, etc).
- java.nio.channels: Define canales, abstracciones mediante los cuales
pueden transferirse datos entre los buffers y las fuentes de datos
(socket, fichero, dispositivo hardware). Además, proporciona clases que
permite E/S sin bloqueo.
- java.nio.charset: Contiene clases que convierten de manera muy eficaz
buffers de bytes en bytes de caracteres. Permiten el uso de expresiones
regulares.
USO DE PAQUETE JAVA.NIO

Características principales de NIO


- Incorpora buffers (contenedores de datos), canales (encargados de la
transferencia de datos entre buffers y las peticiones de E/S) y
selectores (proporcionan el estado de los canales).

- Permite la transferencia eficaz de grandes cantidades de datos. Java.io


emplea flujos de bytes, java.nio, usa bloques de datos.
USO DE PAQUETE JAVA.NIO

Características principales de NIO


- Socket de NIO permiten trabajar sin bloqueo (también permiten
bloqueo). Sin bloqueo, un solo hilo puede encargarse de controlar
tantos canales como se precise. No se necesita destinar un hilo a cada
canal  aumento del rendimiento de E/S. Además se reduce la
complejidad del código (no necesario un hilo por socket).
- Aprovecha las prestaciones del sistema operativo donde se ejecuta la
JVM.
USO DE PAQUETE JAVA.NIO

Características principales de NIO


En resumen:
- NIO es más eficiente que la API de java.io para leer y escribir
cantidades importantes de datos pero no para manipularlos. java.io se
sigue necesitando para el tratamiento de los datos
- Utilidad de NIO para transferir con rapidez grandes bloques de datos,
eliminar cuellos de botella que provocan java.io o usar socket sin
bloqueo.
USO DEL PAQUETE JAVA.NIO
USO DEL PAQUETE JAVA.NIO
Jerarquía de Buffers
Jerarquía de Channels
USO DEL PAQUETE JAVA.NIO
10. Herramientas
OBJETIVOS DE LA UNIDAD

 Herramientas runtime
 Jmaps

 Jps, jconsole, jinfo, jstat


HERRAMIENTAS

 Jps: Listado de JVM del sistema


 Jmap: Imprime mapas de memoria de objetos
compartidos o los detalles de la memoria
heap.
 Jstat: Muestra estadísticas de rendimiento de
JVM
http://java.sun.com/j2se/1.5.0/docs/tooldocs/share/jstat.html#output_options

 Jinfo: Imprime información de un proceso Java.


HERRAMIENTAS

JConsole
Permite la monitorización de la máquina virtual.
Visualiza:
- Uso de memoria Heap
- Hilos
- Clases cargadas
- % CPU utilizada.
Jconsole
HERRAMIENTAS
Jconsole
HERRAMIENTAS

Vous aimerez peut-être aussi