Lenguaje Java Sesin 1 Introduccin al Lenguaje Java

  • Slides: 147
Download presentation
Lenguaje Java Sesión 1: Introducción al Lenguaje Java

Lenguaje Java Sesión 1: Introducción al Lenguaje Java

Índice • • • Java Introducción a Java Conceptos de POO Elementos de un

Índice • • • Java Introducción a Java Conceptos de POO Elementos de un programa Java Herencia, interfaces, polimorfismo Hilos Clases útiles Lenguaje Java 2

Java • Java es un lenguaje OO creado por Sun Microsystems para poder funcionar

Java • Java es un lenguaje OO creado por Sun Microsystems para poder funcionar en distintos tipos de procesadores y máquinas. • Similar a C o C++, pero con algunas características propias (gestión de hilos, ejecución remota, etc) • Independiente de la plataforma, gracias a la JVM (Java Virtual Machine), que interpreta los ficheros objeto • Se dispone de antemano de la API (Application Programming Interface) de clases de Java Lenguaje Java 3

Clases • Clases: con la palabra class y el nombre de la clase class

Clases • Clases: con la palabra class y el nombre de la clase class Mi. Clase {. . . } • Como nombre utilizaremos un sustantivo • Puede estar formado por varias palabras • Cada palabra comenzará con mayúscula, el resto se dejará en minúscula • Por ejemplo: Data. Input. Stream • Si la clase contiene un conjunto de métodos estáticos o constantes relacionadas pondremos el nombre en plural • Por ejemplo: Resources Java Lenguaje Java 4

Campos y variables • • Campos y variables: simples o complejos Utilizaremos sustantivos como

Campos y variables • • Campos y variables: simples o complejos Utilizaremos sustantivos como nombres Properties propiedades; File fichero. Entrada; int num. Vidas; • Puede estar formado por varias palabras, con la primera en minúsculas y el resto comenzando por mayúsculas y el resto en minúsculas • Por ejemplo: num. Vidas • En caso de tratarse de una colección de elementos, utilizaremos plural • Por ejemplo: clientes • Para variables temporales podemos utilizar nombres cortos, como las iniciales de la clase a la que pertenezca, o un carácter correspondiente al tipo de dato int i; Vector v; Data. Input. Stream dis; Java Lenguaje Java 5

Constantes • Constantes: Se declarán como final y static final static String TITULO_MENU =

Constantes • Constantes: Se declarán como final y static final static String TITULO_MENU = “Menu”; final static int ANCHO_VENTANA = 640; final static double PI = 3. 1416; • El nombre puede contener varias palabras • Las palabras se separan con ‘_’ • Todo el nombre estará en mayúsculas • Por ejemplo: MAX_MENSAJES Java Lenguaje Java 6

Métodos • Métodos: con el tipo devuelto, nombre y parámetros void imprimir(String mensaje) {.

Métodos • Métodos: con el tipo devuelto, nombre y parámetros void imprimir(String mensaje) {. . . // Codigo del método } Vector insertar. Vector(Object elemento, int posicion) {. . . // Codigo del método } • Los nombres de los métodos serán verbo • Puede estar formados por varias palabras, con la primera en minúsculas y el resto comenzando por mayúsculas y el resto en minúsculas • Por ejemplo: imprimir. Datos Java Lenguaje Java 7

Constructores • Constructores: se llaman igual que la clase, y se ejecutan con el

Constructores • Constructores: se llaman igual que la clase, y se ejecutan con el operador new para reservar memoria Mi. Clase() {. . . // Codigo del constructor } Mi. Clase(int valor. A, Vector valor. V) {. . . // Codigo del otro constructor } • No hace falta destructor, de eso se encarga el garbage collector • Constructor superclase: super(…) Java Lenguaje Java 8

Paquetes • Paquetes: organizan las clases en una jerarquía de paquetes y subpaquetes •

Paquetes • Paquetes: organizan las clases en una jerarquía de paquetes y subpaquetes • Para indicar que una clase pertenece a un paquete o subpaquete se utiliza la palabra package al principio de la clase package paquete 1. subpaquete 1; class Mi. Clase { • Para utilizar clases de un paquete en otro, se colocan al principio sentencias import con los paquetes necesarios: package otropaquete; import paquete 1. subpaquete 1. Mi. Clase; import java. util. *; class Mi. Otra. Clase { Java Lenguaje Java 9

Paquetes • Si no utilizamos sentencias import, deberemos escribir el nombre completo de cada

Paquetes • Si no utilizamos sentencias import, deberemos escribir el nombre completo de cada clase del paquete no importado (incluyendo subpaquetes) class Mi. Otra. Clase { paquete 1. subpaquete 1. Mi. Clase a =. . . ; // Sin import Mi. Clase a =. . . ; // Con import • Los paquetes se estructuran en directorios en el disco duro, siguiendo la misma jerarquía de paquetes y subpaquetes. /paquete 1/subpaquete 1/Mi. Clase. java Java Lenguaje Java 10

Paquetes • Siempre se deben incluir las clases creadas en un paquete • Si

Paquetes • Siempre se deben incluir las clases creadas en un paquete • Si no se especifica un nombre de paquete la clase pertenecerá a un paquete “sin nombre” • No podemos importar clases de paquetes “sin nombre”, las clases creadas de esta forma no serán accesibles desde otros paquetes • Sólo utilizaremos paquetes “sin nombre” para hacer una prueba rápida, nunca en otro caso Java Lenguaje Java 11

Convenciones de paquetes • El nombre de un paquete deberá constar de una serie

Convenciones de paquetes • El nombre de un paquete deberá constar de una serie de palabras simples siempre en minúsculas • Se recomienda usar el nombre de nuestra DNS al revés especialistajee. org. especialistajee. prueba • Colocar las clases interdependientes, o que suelan usarse juntas, en un mismo paquete • Separar clases volátiles y estables en paquetes diferentes • Hacer que un paquete sólo dependa de paquetes más estables que él • Si creamos una nueva versión de un paquete, daremos el mismo nombre a la nueva versión sólo si es compatible con la anterior Java Lenguaje Java 12

Tipo enumerado enum Estado. Civil {soltero, casado, divorciado}; Estado. Civil ec = Estado. Civil.

Tipo enumerado enum Estado. Civil {soltero, casado, divorciado}; Estado. Civil ec = Estado. Civil. casado; ec = Estado. Civil. soltero; switch(ec) { case soltero: System. out. println("Es soltero"); break; case casado: System. out. println("Es casado"); break; case divorciado: System. out. println("Es divorciado"); break; } Java Lenguaje Java 13

Otras características • Imports estáticos import static java. lang. Math; … double raiz =

Otras características • Imports estáticos import static java. lang. Math; … double raiz = sqrt(1252. 2); • Argumentos variables public void mi. Func(String param, int. . . args) { for(int i: args) { … } } • Anotaciones (metainformación) • P. ej. , @deprecated Java Lenguaje Java 14

Convenciones generales • • Indentar el código uniformemente Limitar la anchura de las líneas

Convenciones generales • • Indentar el código uniformemente Limitar la anchura de las líneas de código (para impresión) Utilizar líneas en blanco para separar bloques de código Utilizar espacios para separar ciertos elementos en una línea • Documentación: • Utilizar /*. . . */ para esconder código sin borrarlo • Utilizar //. . . para detalles de la implementación • Utilizar javadoc para describir la interfaz de programación Java Lenguaje Java 15

Modificadores de acceso • Las clases y sus elementos admiten unos modificadores de acceso:

Modificadores de acceso • Las clases y sus elementos admiten unos modificadores de acceso: • privado: el elemento es accesible sólo desde la clase en que se encuentra • protegido: el elemento es accesible desde la propia clase, desde sus subclases, y desde clases del mismo paquete • público: el elemento es accesible desde cualquier clase • paquete: el elemento es accesible desde la propia clase, o desde clases del mismo paquete. Java Lenguaje Java 16

Modificadores de acceso • private se utiliza para elementos PRIVADOS • protected se utiliza

Modificadores de acceso • private se utiliza para elementos PRIVADOS • protected se utiliza para elementos PROTEGIDOS • public se utiliza para elementos PUBLICOS • No se especifica nada para elementos PAQUETE public class Mi. Clase { private int n; protected void metodo() {. . . } • Todo fichero Java debe tener una y solo una clase pública, llamada igual que el fichero (más otras clases internas que pueda tener) Java Lenguaje Java 17

Modificadores de acceso public La misma clase Cualquier clase del mismo paquete Subclase de

Modificadores de acceso public La misma clase Cualquier clase del mismo paquete Subclase de otro paquete Cualquier clase de otro paquete sí sí sí protected default private sí Java Lenguaje Java 18

Otros modificadores • abstract: para definir clases y métodos abstractos • static: para definir

Otros modificadores • abstract: para definir clases y métodos abstractos • static: para definir elementos compartidos por todos los objetos que se creen de la misma clase • miembros que no pertenecen al objeto en si, sino a la clase • dentro de un método estático sólo podemos utilizar elementos estáticos, o elementos que hayamos creado dentro del propio método • final: para definir elementos no modificables ni heredables public abstract class Mi. Clase { public static final int n = 20; public abstract void metodo(); . . . Java Lenguaje Java 19

Otros modificadores • volatile y synchronized: para elementos a los que no se puede

Otros modificadores • volatile y synchronized: para elementos a los que no se puede acceder al mismo tiempo desde distintos hilos de ejecución – volatile no proporciona atomicidad pero es más eficiente volatile int contador; contador++; //puede causar problemas, son 3 operaciones diferentes – synchronized se usa sobre bloques de código y métodos synchronized(this){ contador++; } Java Lenguaje Java 20

Otros modificadores • native: para métodos que están escritos en otro lenguaje, por ejemplo

Otros modificadores • native: para métodos que están escritos en otro lenguaje, por ejemplo en C++, utilizando JNI (Java Native Interface) • transient: para atributos que no forman parte de la persistencia de objeto, para evitar que se serialicen • strictfp: evitar que se utilice toda la precisión de punto flotante que proporcione la arquitectura. Usar el estándar del IEEE para float y double. No es aconsejable a menos que sea necesario. Java Lenguaje Java 21

Herencia y polimorfismo • Herencia: definir una clase a partir de otra existente •

Herencia y polimorfismo • Herencia: definir una clase a partir de otra existente • La nueva clase “hereda” todos los campos y métodos de la clase a partir de la que se crea, y aparte puede tener los suyos propios • Ejemplo: a partir de una clase Animal podemos definir otras más concretas como Pato, Elefante… • Polimorfismo: si tenemos un método en cualquier clase que sea dibuja (Animal a), podemos pasarle como parámetro tanto un objeto Animal como cualquier subtipo que herede directa o indirectamente de él (Elefante, Pato…) Java Lenguaje Java 22

Clases abstractas e interfaces • Una clase abstracta es una clase que deja algunos

Clases abstractas e interfaces • Una clase abstracta es una clase que deja algunos métodos sin código, para que los rellenen las subclases que hereden de ella public abstract class Mi. Clase { public abstract void metodo 1(); public void metodo 2() {. . . } } • Un interfaz es un elemento que sólo define la cabecera de sus métodos, para que las clases que implementen dicha interfaz rellenen el código según sus necesidades. public interface Runnable { public void run(); } • Asignaremos un nombre a los interfaces de forma similar a las clases, pudiendo ser en este caso adjetivos o sustantivos. Java Lenguaje Java 23

Herencia e interfaces • Herencia • Definimos una clase a partir de otra que

Herencia e interfaces • Herencia • Definimos una clase a partir de otra que ya existe • Utilizamos la palabra extends para decir que una clase hereda de otra (Pato hereda de Animal): class Pato extends Animal • Relación “es”: Un pato ES un animal • Interfaces • Utilizamos la palabra implements para decir que una clase implementa los métodos de una interfaz class Mi. Hilo implements Runnable { public void run() {. . . // Codigo del método } • Relación “actúa como”: Mi. Hilo ACTÚA COMO ejecutable Java Lenguaje Java 24

Polimorfismo • Si una variable es del tipo de la superclase, podemos asignarle también

Polimorfismo • Si una variable es del tipo de la superclase, podemos asignarle también un objeto de la clase hija Animal a = new Pato(); • Si una variable es del tipo de una interfaz implementada por nuestra clase, podemos asignarle también un objeto de esta clase Runnable r = new Mi. Hilo(); • Sólo se puede heredar de una clase, pero se pueden implementar múltiples interfaces: class Pato extends Animal implements Runnable, Action. Listener Java Lenguaje Java 25

Punteros this y super • this se utiliza para hacer referencia a los elementos

Punteros this y super • this se utiliza para hacer referencia a los elementos de la propia clase: class Mi. Clase { int i; Mi. Clase(int i) { this. i = i; // i de la clase = i del parámetro • super se utiliza para llamar al mismo método en la superclase: class Mi. Clase extends Otra. Clase{ Mi. Clase(int i) { super(i); // Constructor de Otra. Clase(. . . ) Java Lenguaje Java 26

Object • Clase base de todas las demás • Todas las clases heredan en

Object • Clase base de todas las demás • Todas las clases heredan en última instancia de ella • Es importante saber las dependencias (herencias, interfaces, etc) de una clase para saber las diferentes formas de instanciarla o referenciarla (polimorfismo) Java Lenguaje Java 27

Ejemplo de polimorfismo • Por ejemplo, si tenemos: public class Mi. Clase extends Thread

Ejemplo de polimorfismo • Por ejemplo, si tenemos: public class Mi. Clase extends Thread implements List • Podremos referenciar un objeto Mi. Clase de estas formas: Mi. Clase mc = new Mi. Clase(); Thread t = new Mi. Clase(); List l = new Mi. Clase(); Object o = new Mi. Clase(); Java Lenguaje Java 28

Object: objetos diferentes • También es importante distinguir entre entidades independientes y referencias: Mi.

Object: objetos diferentes • También es importante distinguir entre entidades independientes y referencias: Mi. Clase mc 1 = new Mi. Clase(); Mi. Clase mc 2 = mc 1; // Es distinto a: Mi. Clase mc 2 = (Mi. Clase)(mc 1. clone()); • El método clone de cada objeto sirve para obtener una copia en memoria de un objeto con los mismos datos, pero con su propio espacio • No realiza una copia en profundidad • Si queremos hacer copias de los objetos que tenga como campos debe sobrescribir este método Java Lenguaje Java 29

Object: comparar objetos • Cuando queremos comparar dos objetos entre sí (por ejemplo, de

Object: comparar objetos • Cuando queremos comparar dos objetos entre sí (por ejemplo, de la clase Mi. Clase), no se hace así: if (mc 1 == mc 2) • Sino con su método equals: if (mc 1. equals(mc 2)) • Deberemos redefinir este método en las clases donde lo vayamos a usar, para asegurarnos de que los objetos se comparan bien • Notar que la clase String, es un subtipo de Object por lo que para comparar cadenas. . . : if (cadena == “Hola”). . . // NO if (cadena. equals(“Hola”)). . . // SI Java Lenguaje Java 30

Object: representar en cadenas • Muchas veces queremos imprimir un objeto como cadena. Por

Object: representar en cadenas • Muchas veces queremos imprimir un objeto como cadena. Por ejemplo, si es un punto geométrico, sacar su coordenada X, una coma, y su coordenada Y • La clase Object proporciona un método to. String para definir cómo queremos que se imprima un objeto. Podremos redefinirlo a nuestro gusto public class Punto 2 D {. . . public String to. String() { return “(“ + x + ”, ” + y + ”)”; } }. . . Punto 2 D p =. . . ; System. out. println(p); // Imprimirá (x, y) del punto Java Lenguaje Java 31

Properties • Esta clase es un tipo de tabla hash que almacena una serie

Properties • Esta clase es un tipo de tabla hash que almacena una serie de propiedades, cada una con un valor asociado • Además, permite cargarlas o guardarlas en algún dispositivo (fichero) • Algunos métodos interesantes: Object set. Property(Object clave, Object valor) Object get. Property(Object clave, Object default) void load(Input. Stream entrada) void store(Output. Stream salida, String cabecera) Java Lenguaje Java 32

System • Ofrece métodos y campos útiles del sistema, como el ya conocido System.

System • Ofrece métodos y campos útiles del sistema, como el ya conocido System. out. println • Otros métodos interesantes de esta clase (todos estáticos): void long void Java exit(int estado) gc() current. Time. Millis() array. Copy(Object fuente, int pos_fuente, Object destino, int pos_destino, int num. Elementos) Lenguaje Java 33

Otras clases • La clase Math proporciona una serie de métodos (estáticos) útiles para

Otras clases • La clase Math proporciona una serie de métodos (estáticos) útiles para diferentes operaciones matemáticas (logaritmos, potencias, exponenciales, máximos, mínimos, etc) • Otras clases útiles son la clase Calendar (para trabajar con fechas y horas), la clase Currency (para monedas), y la clase Locale (para situarnos en las características de fecha, hora y moneda de una región del mundo) Java Lenguaje Java 34

Transfer Objects • Encapsulan datos con los que normalmente se trabaja de forma conjunta

Transfer Objects • Encapsulan datos con los que normalmente se trabaja de forma conjunta • Nos permiten transferir estos datos entre las diferentes capas de la aplicación public class Usuario { private String login; private String password; private boolean administrador; } Java Lenguaje Java 35

Getters y Setters • Es buena práctica de programación declarar todos los campos de

Getters y Setters • Es buena práctica de programación declarar todos los campos de las clases privados • Para acceder a ellos utilizaremos métodos • Getters para obtener el valor del campo • Setters para modificar el valor del campo • Estos métodos tendrán prefijo get y set respectivamente, seguido del nombre del campo al que acceden, pero comenzando por mayúscula • Por ejemplo: get. Login(), set. Login(String login) • El getter para campos booleanos tendrá prefijo is en lugar de get • Por ejemplo: is. Administrador() Java Lenguaje Java 36

Bean. Utils • Utilidades de la biblioteca commons-beanutils de Apache. • Bean. Utils. copy.

Bean. Utils • Utilidades de la biblioteca commons-beanutils de Apache. • Bean. Utils. copy. Properties(obj. Destino, obj. Origen) • Copia los campos comunes entre los dos objetos • Los reconoce usando la API de Reflection • La identificación está basada en los nombres de los getters y los setters y en su tipo de dato. • Ejemplo: int origen. get. Nombre. Campo( ), e void destino. set. Nombre. Campo(int n). Java Lenguaje Java 37

Bean. Utils • Ejemplo: proyección de un punto 3 D en un punto 2

Bean. Utils • Ejemplo: proyección de un punto 3 D en un punto 2 D. • En lugar de copiar todos los campos uno a uno: punto 2 D. set. X(punto 3 D. get. X()); punto 2 D. set. Y(punto 3 D. get. Y()); punto 2 D. set. Descripcion(punto 3 D. get. Descripcion()); • usamos copy. Properties: public class Punto 2 D { private int x; private int y; private String descripcion; public String get. Descripcion() { return descripcion; } public void set. Descripcion(String descripcion) { this. descripcion = descripcion; } public int get. X() { return x; } public void set. X(int x) { this. x = x; } public int get. Y() { return y; } public void set. Y(int y) { this. y = y; } } public class Punto 3 D { private int x; private int y; private int z; private String descripcion; /*. . . y los getters y setters para los cuatro campos */ } Bean. Utils. copy. Properties(punto 2 D, punto 3 D); Java Lenguaje Java 38

Lenguaje Java Sesión 2: Colecciones de datos

Lenguaje Java Sesión 2: Colecciones de datos

Índice • • • Java Introducción Colecciones Enumeraciones e iteradores Polimorfismo e interfaces Wrappers

Índice • • • Java Introducción Colecciones Enumeraciones e iteradores Polimorfismo e interfaces Wrappers de tipos básicos Colecciones 40

Introducción • Java proporciona un amplio conjunto de clases útiles para desarrollar aplicaciones •

Introducción • Java proporciona un amplio conjunto de clases útiles para desarrollar aplicaciones • En esta sesión veremos algunos grupos de ellas: • Clases útiles para crear y gestionar diferentes tipos de colecciones • Clases para recorrer, ordenar y manipular las colecciones • Clases para encapsular nuestros tipos de datos Java Colecciones 41

Colecciones • En el paquete java. util • Representan grupos de objetos, llamados elementos

Colecciones • En el paquete java. util • Representan grupos de objetos, llamados elementos • Podemos encontrar de distintos tipos, según si sus elementos están ordenados, si permiten repetir elementos, etc • La interfaz Collection define el esqueleto que deben tener todos los tipos de colecciones • Por tanto, todos tendrán métodos generales como: • • Java boolean add(Object o) boolean remove(Object o) boolean contains(Object o) void clear() boolean is. Empty() Iterator iterator() int size() Object[] to. Array() Colecciones 42

Listas de elementos • La interfaz List hereda de Collection • Operaciones propias de

Listas de elementos • La interfaz List hereda de Collection • Operaciones propias de una colección tipo lista • Los elementos tienen un orden (posición en la lista) • Así, tendremos otros nuevos métodos, además de los de Collection: • • • Java void add(int posicion, Object o) Object get(int indice) int index. Of(Object o) Object remove(int indice) Object set(int indice, Object o) Colecciones 43

Tipos de listas • Array. List: implementa una lista de elementos mediante un array

Tipos de listas • Array. List: implementa una lista de elementos mediante un array de tamaño variable • NO sincronizado • Vector: existe desde las primeras versiones de Java, después se acomodó al marco de colecciones implementando la interfaz List. • Similar a Array. List, pero SINCRONIZADO. Tiene métodos anteriores a la interfaz List: • • • void add. Element(Object o) / boolean remove. Element(Object o) void insert. Element. At(Object o, int posicion) void remove. Element. At(Object o, int posicion) Object element. At(int posicion) void set. Element. At(Object o, int posicion) int size() • Linked. List: lista doblemente enlazada. Útil para simular pilas o colas • • • Java void add. First(Object o) / void add. Last(Object o) Object get. First() / Object get. Last() Object remove. First() / Object remove. Last() Colecciones 44

Conjuntos • Grupos de elementos donde no hay repetidos • Consideramos dos objetos de

Conjuntos • Grupos de elementos donde no hay repetidos • Consideramos dos objetos de una clase iguales si su método equals los da como iguales • o 1. equals(o 2) es true • Los conjuntos se definen en la interfaz Set, que, como List, también hereda de Collection • El método add definido en Collection devolvía un booleano, que en este caso permitirá saber si se insertó el elemento en el conjunto, o no (porque ya existía) Java Colecciones 45

Tipos de conjuntos • Hash. Set: los objetos del conjunto se almacenan en una

Tipos de conjuntos • Hash. Set: los objetos del conjunto se almacenan en una tabla hash. • El coste de inserción, borrado y modificación suele ser constante • La iteración es más costosa, y el orden puede diferir del orden de inserción • Linked. Hash. Set: como la anterior, pero la tabla hash tiene los elementos enlazados, lo que facilita la iteración • Tree. Set: guarda los elementos en un árbol • El coste de las operaciones es logarítmico Java Colecciones 46

Mapas • No forman parte del marco de colecciones • Se definen en la

Mapas • No forman parte del marco de colecciones • Se definen en la interfaz Map, y sirven para relacionar un conjunto de claves (keys) con sus respectivos valores • Tanto la clave como el valor pueden ser cualquier objeto • • • Java Object get(Object clave) Object put(Object clave, Object valor) Object remove(Object clave) Set key. Set() int size() Colecciones 47

Tipos de mapas • Hash. Map: Utiliza una tabla hash para almacenar los pares

Tipos de mapas • Hash. Map: Utiliza una tabla hash para almacenar los pares clave=valor. • Las operaciones básicas (get y put) se harán en tiempo constante si la dispersión es adecuada • La iteración es más costosa, y el orden puede diferir del orden de inserción • Hashtable: como la anterior, pero SINCRONIZADA. Como Vector, está desde las primeras versiones de Java • Enumeration keys() • Tree. Map: utiliza un árbol para implementar el mapa • El coste de las operaciones es logarítmico • Los elementos están ordenados ascendentemente por clave Java Colecciones - 48

Genéricos • Colecciones de tipos concretos de datos • A partir de JDK 1.

Genéricos • Colecciones de tipos concretos de datos • A partir de JDK 1. 5 • Aseguran que se utiliza el tipo de datos correcto Array. List<String> a = new Array. List<String>(); a. add("Hola"); String s = a. get(0); • Podemos utilizar genéricos en nuestras propias clases Java Colecciones - 49

Enumeraciones e iteradores • Las enumeraciones y los iteradores no son tipos de datos

Enumeraciones e iteradores • Las enumeraciones y los iteradores no son tipos de datos en sí, sino objetos útiles a la hora de recorrer diferentes tipos de colecciones • Con las enumeraciones podremos recorrer secuencialmente los elementos de una colección, para sacar sus valores, modificarlos, etc • Con los iteradores podremos, además de lo anterior, eliminar elementos de una colección, con los métodos que proporciona para ello. Java Colecciones - 50

Enumeraciones • La interfaz Enumeration permite consultar secuencialmente los elementos de una colección •

Enumeraciones • La interfaz Enumeration permite consultar secuencialmente los elementos de una colección • Para recorrer secuencialmente los elementos de la colección utilizaremos su método next. Element: Object item = enum. next. Element(); • Para comprobar si quedan más elementos que recorrer, utilizamos el método has. More. Elements: if (enum. has. More. Elements()). . . Java Colecciones - 51

Enumeraciones • Con lo anterior, un bucle completo típico para recorrer una colección utilizando

Enumeraciones • Con lo anterior, un bucle completo típico para recorrer una colección utilizando su enumeración de elementos sería: // Obtener la enumeracion Enumeration enum = coleccion. elements(); while (enum. has. More. Elements()) { Object item = enum. next. Element(); . . . // Convertir item al objeto adecuado y // hacer con el lo que convenga } Java Colecciones - 52

Iteradores • La interfaz Iterator permite iterar secuencialmente sobre los elementos de una colección

Iteradores • La interfaz Iterator permite iterar secuencialmente sobre los elementos de una colección • Para recorrer secuencialmente los elementos de la colección utilizaremos su método next: Object item = iter. next(); • Para comprobar si quedan más elementos que recorrer, utilizamos el método has. Next: if (iter. has. Next()). . . • Para eliminar el elemento de la posición actual del iterador, utilizamos su método remove: iter. remove(); Java Colecciones - 53

Iteradores • Con lo anterior, un bucle completo típico para recorrer una colección utilizando

Iteradores • Con lo anterior, un bucle completo típico para recorrer una colección utilizando su iterador sería: // Obtener el iterador Iterator iter = coleccion. iterator(); while (iter. has. Next()) { Object item = iter. next(); . . . // Convertir item al objeto adecuado y // hacer con el lo que convenga, por ejemplo iter. remove(); } Java Colecciones - 54

Bucles sin iteradores • Nueva versión del for en JDK 1. 5 • Permite

Bucles sin iteradores • Nueva versión del for en JDK 1. 5 • Permite recorrer tanto arrays como colecciones • Previene salirse del rango de forma segura List<String> lista = obtener. Lista(); for(String cadena: lista) System. out. println (cadena); Java Colecciones - 55

Polimorfismo e interfaces • Hacer referencia siempre mediante la interfaz • Permite cambiar la

Polimorfismo e interfaces • Hacer referencia siempre mediante la interfaz • Permite cambiar la implementación sin afectar al resto del programa public class Cliente { List<Cuenta> cuentas; public Cliente() { this. cuentas = new Array. List<Cuenta>(); } public List<Cuenta> get. Cuentas() { return cuentas; } } Java Colecciones - 56

Ejemplo: Algoritmos • La clase Collections dispone de una serie de métodos útiles para

Ejemplo: Algoritmos • La clase Collections dispone de una serie de métodos útiles para operaciones tediosas, como ordenar una colección, hacer una búsqueda binaria, sacar su valor máximo, etc • • static void sort(List lista) static int binary. Search(List lista, Object objeto) static Object max(Collection col). . . • Sirven para cualquier implementación de List Java Colecciones - 57

Comparación de objetos Java Los objetos deben ser correctamente comparables para ser compatibles con

Comparación de objetos Java Los objetos deben ser correctamente comparables para ser compatibles con las estructuras de datos y algoritmos. Comparación de igualdad: equals( ) Comparación de mayor o menor: clase Comparator o interfaz Comparable Colecciones - 58

Sobrecarga de Equals Object. equals(Object o) public class Mi. Clase {. . . @Override

Sobrecarga de Equals Object. equals(Object o) public class Mi. Clase {. . . @Override public boolean equals(Object o) { // return true o false, según un criterio } } Java Colecciones - 59

Evitar la sobrecarga de Equals si: Java Cada instancia es intrínsecamente única. Por ejemplo,

Evitar la sobrecarga de Equals si: Java Cada instancia es intrínsecamente única. Por ejemplo, instancias de hilos, que representan entidades activas, y no tan sólo un conjunto de valores. Cuando no es necesaria una comparación lógica. Por ejemplo, dos números aleatorios, donde la igualdad puede ocurrir pero su comprobación no es necesaria. Una superclase ya sobrecarga equals, y el comportamiento de éste es apropiado para la clase actual. Colecciones - 60

Propiedades que debe cumplir Simetría: para cualquier par de instancias no nulas, x. equals(y)

Propiedades que debe cumplir Simetría: para cualquier par de instancias no nulas, x. equals(y) devuelve verdadero si y sólo si y. equals(x) también devuelve verdadero. Transitividad: si x. equals(y)==true y y. equals(z)==true, entonces x. equals(z) también será verdadero, para cualesquiera instancias no nulas.

Sobrecargar hash. Code( ) Cuando hash. Code es invocado varias veces para el mismo

Sobrecargar hash. Code( ) Cuando hash. Code es invocado varias veces para el mismo objeto, debe devolver consistentemente el mismo entero, siempre que no se haya modificado ninguna información que afecte al resultado de equals. Esta consistencia debe mantenerse entre distintas ejecuciones de la misma aplicación. Si dos objetos son iguales según equals, entonces los métodos hash. Code de ambos deben devolver el mismo entero.

Comparar implementando Comparable Permite establecer un orden entre objetos Se necesita decidir qué características

Comparar implementando Comparable Permite establecer un orden entre objetos Se necesita decidir qué características del objeto establecen dicho orden public class Persona implements Comparable<Persona> { public int id; public String apellido; . . . @Override public int compare. To(Persona p) { return this. id - p. id; } } Java Colecciones - 63

Comparador externo: Comparator Puede extenderse o bien desde una clase externa, o bien desde

Comparador externo: Comparator Puede extenderse o bien desde una clase externa, o bien desde la propia clase cuyos objetos deben ser comparados public class Compara. Persona. Por. Nombre implements Comparator<Persona>{ public int compare(Persona p 1, Persona p 2) { return p 1. apellido. compare. To. Ignore. Case(p 2. apellido); } }. . . List personas = new Array. List<Persona>(); personas. add(p 1); personas. add(p 2); personas. add(p 3); //. . . Collections. sort(personas); //Comparable. compare. To Collections. sort(personas, new Compara. Persona. Por. Nombre()); //Comparator. compare Java Colecciones - 64

Ejemplo: Wrappers de colecciones • Objetos que envuelven la instancia de una colección existente

Ejemplo: Wrappers de colecciones • Objetos que envuelven la instancia de una colección existente • Implementa la misma interfaz (p. ej List) • No conocemos la clase concreta del wrapper • Cambia el comportamiento de algunos métodos • Sincronizar acceso a la colección List Collections. synchronized. List(List l) • Hacerla de sólo lectura List Collections. unmodifiable. List(List l) Java Colecciones - 65

Wrappers • Los tipos simples (int, char, float, double, etc) no pueden incluirse directamente

Wrappers • Los tipos simples (int, char, float, double, etc) no pueden incluirse directamente en colecciones, ya que éstas esperan subtipos de Object en sus métodos • Para poderlos incluir, se tienen unas clases auxiliares, llamadas wrappers, para cada tipo básico, que lo convierten en objeto complejo • Estas clases son, respectivamente, Integer, Character, Float, Double, etc. • Encapsulan al tipo simple y ofrecen métodos útiles para poder trabajar con ellos Java © 2012 -2013 Depto. Ciencia de la Computación e IA Colecciones - 66

Wrappers • Si quisiéramos incluir un entero en un Array. List, lo podríamos hacer

Wrappers • Si quisiéramos incluir un entero en un Array. List, lo podríamos hacer así: int a; Array. List al = new Array. List(); al. add(new Integer(a)); • Si quisiéramos recuperar un entero de un Array. List, lo podríamos hacer así: Integer entero = (Integer)(al. get(posicion)); int a = entero. int. Value(); Java © 2012 -2013 Depto. Ciencia de la Computación e IA Colecciones - 67

Autoboxing • Conversiones automáticas entre tipos básicos y sus wrappers Integer n = 10;

Autoboxing • Conversiones automáticas entre tipos básicos y sus wrappers Integer n = 10; int num = n; List<Integer> lista= new Array. List<Integer>(); lista. add(10); int elem = lista. get(0); Java © 2012 -2013 Depto. Ciencia de la Computación e IA Colecciones - 68

Lenguaje Java Sesión 3: Tratamiento de errores

Lenguaje Java Sesión 3: Tratamiento de errores

Índice • • • Excepciones Captura de excepciones Propagación de excepciones Nested exceptions Errores

Índice • • • Excepciones Captura de excepciones Propagación de excepciones Nested exceptions Errores en tiempo de compilación Tipos genéricos

Tratamiento de errores en tiempo de ejecución • Excepción: Evento que sucede durante la

Tratamiento de errores en tiempo de ejecución • Excepción: Evento que sucede durante la ejecución del programa y que hace que éste salga de su flujo normal de ejecución • Se lanzan cuando sucede un error • Se pueden capturar para tratar el error • Son una forma elegante para tratar los errores en Java • Separa el código normal del programa del código para tratar errores.

Jerarquía

Jerarquía

Tipos de excepciones • Es Checked: Derivadas de Exception obligatorio capturarlas o declarar que

Tipos de excepciones • Es Checked: Derivadas de Exception obligatorio capturarlas o declarar que pueden ser • lanzadas • Se utilizan normalmente para errores que pueden ocurrir durante la ejecución de un programa, normalmente debidos a • factores externos P. ej. Formato de fichero incorrecto, error leyendo disco, etc • Unchecked: Derivadas de Runtime. Exception • Excepciones que pueden ocurrir en cualquier fragmento de código • No hace falta capturarlas (es opcional) • Se utilizan normalmente para errores graves en la lógica de un programa, que no deberían ocurrir • P. ej. Puntero a null, fuera de los límites de un array, etc

Creación de excepciones • Podemos crear cualquier nueva excepción creando una clase que herede

Creación de excepciones • Podemos crear cualquier nueva excepción creando una clase que herede de Exception (checked), Runtime. Exception (unchecked) o de cualquier subclase de las anteriores. public class Mi. Excepcion extends Exception { public Mi. Excepcion (String mensaje) { super(mensaje); } }

try-catch-finally try { // Código regular del programa // Puede producir excepciones } catch(Tipo.

try-catch-finally try { // Código regular del programa // Puede producir excepciones } catch(Tipo. De. Excepcion 1 e 1) { // Código que trata las excepciones de tipo // Tipo. De. Excepcion 1 o subclases de ella. // Los datos sobre la excepción los encontraremos // en el objeto e 1. . } catch(Tipo. De. Excepcion. N e. N) { // Código que trata las excepciones de tipo // Tipo. De. Excepcion. N o subclases de ella. } finally { // Código de finalización (opcional) }

Ejemplos Sólo captura Array. Out. Of. Bounds. Exception int [] hist = lee. Histograma();

Ejemplos Sólo captura Array. Out. Of. Bounds. Exception int [] hist = lee. Histograma(); try { for(int i=1; ; i++) hist[i] += hist[i-1]; } catch(Array. Out. Of. Bounds. Exception e) { System. out. println(“Error: “ + e. get. Message()); } Captura cualquier excepción int [] hist = lee. Histograma(); try { for(int i=1; ; i++) hist[i] += hist[i-1]; } catch(Exception e) { System. out. println(“Error: “ + e. get. Message()); }

Información sobre la excepción • Mensaje de error String msg = e. get. Message();

Información sobre la excepción • Mensaje de error String msg = e. get. Message(); • Traza e. print. Stack. Trace(); • Cada tipo concreto de excepción ofrece información especializada para el error que representa • P. ej. Parse. Exception ofrece el número de la línea del fichero donde ha encontrado el error

Lanzar una excepción • Para lanzar una excepción debemos • Crear el objeto correspondiente

Lanzar una excepción • Para lanzar una excepción debemos • Crear el objeto correspondiente a la excepción Exception e = new Parse. Exception(mensaje, linea); • Lanzar la excepción con una instrucción throw e; • Si la excepción es checked, declarar que el método puede lanzarla con throws public void lee. Fichero() throws Parse. Exception {. . . throw new Parse. Exception(mensaje, linea); . . . }

Capturar o propagar • Si un método lanza una excepción checked deberemos • Declarar

Capturar o propagar • Si un método lanza una excepción checked deberemos • Declarar que puede ser lanzada para propagarla al método llamador public void init() throws Parse. Exception { lee. Fichero(); } • O capturarla para que deje de propagarse try { lee. Fichero(); } catch(Parse. Exception e) { System. out. println(“Error en linea “ + e. get. Offset() + “: “ + e. get. Message()); } • Si es unchecked • Se propaga al método llamante sin declarar que puede ser lanzada • Parará de propagarse cuando sea capturada • Si ningún método la captura, la aplicación terminará automáticamente mostrándose la traza del error producido

Nested exceptions • Captura excepción causante • Lanza excepción propia try {. . .

Nested exceptions • Captura excepción causante • Lanza excepción propia try {. . . } catch(IOException e) { throw new Mi. Excepcion("Mensaje de error", e); } • Encadena errores producidos. Facilita depuración. • Información detallada del error concreto. • Aislar al llamador de la implementación concreta.

Errores en tiempo de compilación Son preferibles a los de ejecución Errores de sintaxis:

Errores en tiempo de compilación Son preferibles a los de ejecución Errores de sintaxis: ej, falta un punto y coma, referencia a nombre de variable inexistente Errores semánticos: de más alto nivel, ej. intentar usar el valor de una variable que nunca se ha inicializado. Errores en cascada: confunden al compilador y no se localiza correctamente la causa del error. Ej, cuando falta el cierre de una llave.

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Errores en cascada Ejemplo: fo

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Errores en cascada Ejemplo: fo ( int i = 0; i < 4; i++ ){} Prueba. java: 24: '. class' expected fo ( int i = 0; i < 4; i++ ^ Prueba. java: 24: ')' expected fo ( int i = 0; i < 4; i++ ^ Prueba. java: 24: not a statement fo ( int i = 0; i < 4; i++ ^ Pueba. java: 24: '; ' expected fo ( int i = 0; i < 4; i++ ) ) ^ Prueba. java: 24: unexpected type required: value found : class fo ( int i = 0; i < 4; i++ ) ^ Prueba. java: 24: cannot resolve symbol : variable i location: class Prueba fo ( int i = 0; i < 4; i++ ) ^ 6 errors

Warnings Ayudan a mejorar el estilo y la corrección del código Eclipse: permite aumentar

Warnings Ayudan a mejorar el estilo y la corrección del código Eclipse: permite aumentar niveles de warning

Herramientas de análisis Herramientas (externas) de análisis de código fuente Detecta código duplicado, código

Herramientas de análisis Herramientas (externas) de análisis de código fuente Detecta código duplicado, código inalcanzable, código subóptimo, expresiones complicadas, y otras posibles fuentes de bugs Plugin para Eclipse

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Comprobación de tipos: genéricos Antes

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Comprobación de tipos: genéricos Antes de Java 1. 5: List v = new Array. List(); v. add("test"); Integer i = (Integer)v. get(0); // Error en tiempo de ejecución Con tipos genéricos: List<String> v = new Array. List<String>(); v. add("test"); String s = v. get(0); // Correcto (sin necesidad de cast explícito) Integer i = v. get(0); // Error en tiempo ce compilación Java © 2012 -2013 Depto. Ciencia de la Computación e IA Errores - 85

Definición de genéricos public class Entry<K, V> { Interfaces / Clases private final K

Definición de genéricos public class Entry<K, V> { Interfaces / Clases private final K key; private final V value; public interface List<E> { void add(E x); Iterator<E> iterator(); } public interface Iterator<E> { E next(); boolean has. Next(); } public Entry(K k, V v) { key = k; value = v; } public K get. Key() { return key; } public V get. Value() { return value; } Uso Entry<String, String> grade 440 = new Entry<String, String>("mike", "A"); Entry<String, Integer> marks 440 = new Entry<String, Integer>("mike", 100); System. out. println("grade: " + grade 440); System. out. println("marks: " + marks 440); } public String to. String() { return "(" + key + ", " + value + ")"; }

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Métodos genéricos También los métodos

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Métodos genéricos También los métodos se pueden parametrizar con tipos genéricos public static return new } <T> Entry<T, T> twice(T value) { Simple. Immutable. Entry<T, T>(value, value); Entry<String, String> pair = this. <String>twice("Hello"); Entry<String, String> pair = twice("Hello"); // Declarado // Inferido

Subtipos y comodines Array. List<Hija> no es subtipo de Array. List<Padre> Para flexibilizar el

Subtipos y comodines Array. List<Hija> no es subtipo de Array. List<Padre> Para flexibilizar el tipo podemos utilizar el comodín: <? > Para acotar el comodín en la jerarquía de herencia usamos super y extends Permitir clases derivadas: Array. List<? extends Padre> Permitir superclases (clases padre): Array. List<? super Padre>

Tipos genéricos y excepciones Es posible indicar a un método o una clase qué

Tipos genéricos y excepciones Es posible indicar a un método o una clase qué excepción debe lanzar, a través de genéricos public <T extends Throwable> void metodo() throws T { throw new T(); } // O bien public class Clase<T extends Throwable> public void metodo() throws T { throw new T(); } }

Tipos genéricos y excepciones No es posible es crear excepciones con tipos genéricos, debido

Tipos genéricos y excepciones No es posible es crear excepciones con tipos genéricos, debido al “borrado de tipos” Ejemplo, no se puede hacer: public class Mi. Excepcion<T extends Object> extends Exception { private T some. Object; public Mi. Excepcion(T some. Object) { this. some. Object = some. Object; } public T get. Some. Object() { return some. Object; } }

Borrado de tipos porque durante la compilación, tras comprobar que los tipos están bien,

Borrado de tipos porque durante la compilación, tras comprobar que los tipos están bien, éstos se eliminan, el siguiente código pasa a ser: try { //Código que lanza o bien //Mi. Excepcion<String>, o bien //Mi. Excepcion<Integer> } catch(Mi. Excepcion<String> ex) { // A } catch(Mi. Excepcion<Integer> ex) { // B } try { //Código que lanza o bien //Mi. Excepcion<String>, o bien //Mi. Excepcion<Integer> } catch(Mi. Excepcion ex) { // A } catch(Mi. Excepcion ex) { // B }

Lenguaje Java Avanzado Sesión 4: Serialización de datos

Lenguaje Java Avanzado Sesión 4: Serialización de datos

Índice • • Introducción a los flujos de E/S Entrada y salida estándar Acceso

Índice • • Introducción a los flujos de E/S Entrada y salida estándar Acceso a ficheros Acceso a recursos Acceso a URLs Codificación de datos Serialización de objetos

Flujos de E/S • Las aplicaciones muchas veces necesitan enviar datos a un determinado

Flujos de E/S • Las aplicaciones muchas veces necesitan enviar datos a un determinado destino o leerlos de una determinada fuente • Ficheros en disco, red, memoria, otras aplicaciones, etc • Esto es lo que se conoce como E/S • Esta E/S en Java se hace mediante flujos (streams) • Los datos se envían en serie a través del flujo • Se puede trabajar de la misma forma con todos los flujos, independientemente de su fuente o destino

Tipos de flujos según el tipo de datos • Según el tipo de datos

Tipos de flujos según el tipo de datos • Según el tipo de datos que transportan, distinguimos • Flujos de bytes (con sufijos Input. Stream y Output. Stream) • Flujos de caracteres (con sufijos Reader y Writer) • Superclases Entrada Salida Bytes Input. Stream Output. Stream Caracteres Reader Writer

Tipos de flujos según su propósito • Distinguimos: • Canales de datos Simplemente llevan

Tipos de flujos según su propósito • Distinguimos: • Canales de datos Simplemente llevan datos de una fuente a un destino Ficheros: File. Input. Stream, File. Reader, File. Output. Stream, File. Writer Memoria: Byte. Array. Input. Stream, Char. Array. Reader, . . . Tuberías: Piped. Input. Stream, Piped. Reader, Piped. Writer, . . . • Flujos de procesamiento Realizan algún procesamiento con los datos Impresión: Print. Writer, Print. Stream Conversores de datos: Data. Output. Stream, Data. Input. Stream Bufferes: Buffered. Reader

Acceso a los flujos • Todos los flujos tienen una serie de métodos básicos

Acceso a los flujos • Todos los flujos tienen una serie de métodos básicos Flujos Métodos Input. Stream, Reader read, reset, close Output. Stream, Writer write, flush, close • Los flujos de procesamiento • Se construyen a partir de flujos canales de datos • Los extienden proporcionando métodos de más alto nivel, p. ej: Flujos Métodos Buffered. Reader read. Line Data. Output. Stream write. Int, write. UTF, . . . Print. Stream, Print. Writer print, println

Objetos de la E/S estándar • En Java también podemos acceder a la entrada,

Objetos de la E/S estándar • En Java también podemos acceder a la entrada, salida y salida de error estándar • Accedemos a esta E/S mediante flujos • Estos flujos se encuentran como propiedades estáticas de la clase System Tipo de flujo Propiedad Entrada Input. Stream System. in Salida Print. Stream System. out Salida de error Print. Stream System. err

Salida estándar • La salida estándar se ofrece como flujo de procesamiento Print. Stream

Salida estándar • La salida estándar se ofrece como flujo de procesamiento Print. Stream • Con un Output. Stream a bajo nivel sería demasiado incómoda la escritura • Este flujo ofrece los métodos print y println que permiten imprimir cualquier tipo de datos básico • En la salida estándar System. out. println(“Hola mundo”); • En la salida de error System. err. println(“Error”);

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Flujos de ficheros • Canales

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Flujos de ficheros • Canales de datos para acceder a ficheros Entrada Salida Caracteres File. Reader File. Writer Binarios File. Input. Stream File. Output. Stream • Se puede acceder a bajo nivel directamente de la misma forma que para cualquier flujo • Podemos construir sobre ellos flujos de procesamiento para facilitar el acceso de estos flujos

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Lectura y escritura de ficheros

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Lectura y escritura de ficheros public void copia_fichero() { int c; try { File. Reader in = new File. Reader("fuente. txt"); File. Writer out = new File. Writer("destino. txt"); while( (c = in. read()) != -1) { out. write(c); } in. close(); out. close(); } catch(File. Not. Found. Exception e 1) { System. err. println("Error: No se encuentra el fichero"); } catch(IOException e 2) { System. err. println("Error leyendo/escribiendo fichero"); } }

Uso de flujos de procesamiento public void escribe_fichero() { File. Writer out = null;

Uso de flujos de procesamiento public void escribe_fichero() { File. Writer out = null; Print. Writer p_out = null; try { out = new File. Writer("result. txt"); p_out = new Print. Writer(out); p_out. println("Este texto será escrito en el fichero"); } catch(IOException e) { System. err. println("Error al escribir en el fichero"); } finally { p_out. close(); } }

Sistema de ficheros • La clase File contiene utilidades para trabajar con el sistema

Sistema de ficheros • La clase File contiene utilidades para trabajar con el sistema de ficheros • Constantes para indicar los separadores de directorios (‘/’ ó ‘’) Hace las aplicaciones independientes de la plataforma • • • Crear, borrar o renombrar ficheros y directorios Listar los ficheros de un directorio Comprobar y establecer los permisos sobre ficheros Obtener la ruta de un fichero Obtener datos sobre ficheros (tamaño, fecha, etc) Etc. . .

Acceso a recursos • Los recursos incluidos en un JAR no se encuentran directamente

Acceso a recursos • Los recursos incluidos en un JAR no se encuentran directamente en el sistema de ficheros • No podremos utilizar los objetos anteriores para acceder a ellos • Accedemos a un recurso en el JAR con get. Class(). get. Resource. As. Stream(“/datos. txt”); • Anteponiendo ‘/’ se busca de forma relativa al raíz del JAR • Si no, buscará de forma relativa al directorio correspondiente al paquete de la clase actual

URLs • URL = Uniform Resource Locator • Cadena para localizar los recursos en

URLs • URL = Uniform Resource Locator • Cadena para localizar los recursos en Internet • Se compone de protocolo: //servidor[: puerto]/recurso • P. ej. http: //www. ua. es/es/index. html Se conecta al servidor www. ua. es A través del puerto por defecto (puerto 80) Utilizando protocolo HTTP para comunicarse Solicita el recurso /es/index. html

URLs en Java • Se encapsulan en la clase URL url = new URL("http:

URLs en Java • Se encapsulan en la clase URL url = new URL("http: //www. ua. es/es/index. html"); • Es obligatorio especificar el protocolo • P. ej. www. ua. es es una URL mal formada • Si la URL está mal formada se producirá una excepción Malformed. URLException try { URL url = new URL("http: //www. ua. es/es/index. html"); } catch(Malformed. URLException e) { System. err. println("Error: URL mal construida"); }

Lectura del contenido • Podemos leer el contenido de la URL abriendo un flujo

Lectura del contenido • Podemos leer el contenido de la URL abriendo un flujo de entrada con Input. Stream in = url. open. Stream(); • Leeremos de este flujo de la misma forma que con cualquier otro flujo • Con los métodos a bajo nivel (byte a byte) • O utilizando un flujo de procesamiento • P. ej, si la URL corresponde a un documento HTML obtendremos el código fuente de este documento

Codificación • Podemos codificar de forma sencilla los datos para enviarlos a través de

Codificación • Podemos codificar de forma sencilla los datos para enviarlos a través de un flujo de bytes (en serie) • String Utilizaremos un flujo Data. Output. Stream nombre = "Jose"; int edad = 25; Byte. Array. Output. Stream baos = new Byte. Array. Output. Stream(); Data. Output. Stream dos = new Data. Output. Stream(baos); dos. write. UTF(nombre); dos. write. Int(edad); dos. close(); baos. close();

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Descodificación • Para descodificar estos

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Descodificación • Para descodificar estos datos del flujo realizaremos el proceso inverso • Utilizamos un flujo Data. Input. Stream Byte. Array. Input. Stream bais = new Byte. Array. Input. Stream(datos); Data. Input. Stream dis = new Data. Input. Stream(bais); String nombre = dis. read. UTF(); int edad = dis. read. Int(); dis. close(); bais. close();

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Entrada/Salida de objetos • Si

Experto Universitario en Desarrollo de Aplicaciones para Dispositivos Móviles Entrada/Salida de objetos • Si queremos enviar un objeto a través de un flujo deberemos convertirlo a una secuencia de bytes • Esto es lo que se conoce como serialización • Java serializa automáticamente los objetos • Obtiene una codificación del objeto en forma de array de bytes • En este array se almacenarán los valores actuales de todos los campos del objeto serializado Java © 2012 -2013 Depto. Ciencia de la Computación e IA Serialización-110

Objetos serializables • Para que un objeto sea serializable debe cumplir: 1. Implementar la

Objetos serializables • Para que un objeto sea serializable debe cumplir: 1. Implementar la interfaz Serializable public Mi. Clase implements Serializable {. . . } Esta interfaz no obliga a definir ningún método, sólo marca el objeto como serializable 1. Todos los campos deben ser Datos elementales o Objetos serializables

Flujos de objetos • Para enviar o recibir objetos tendremos los flujos de procesamiento

Flujos de objetos • Para enviar o recibir objetos tendremos los flujos de procesamiento Object. Input. Stream Object. Output. Stream • Estos flujos proporcionan respectivamente los métodos read. Object write. Object • Con los que escribir o leer objetos del flujo • Utilizan la serialización de Java para codificarlos y descodificarlos

Lenguaje Java Sesión 5: Hilos

Lenguaje Java Sesión 5: Hilos

Índice • • Creación de hilos y ciclo de vida Sincronización de hilos Bloques

Índice • • Creación de hilos y ciclo de vida Sincronización de hilos Bloques vigilados Interbloqueos Interfaz Lock Variables atómicas y colecciones Ejecutores y pools

Hilos Cada hilo es un flujo de ejecución independiente Tiene su propio contador de

Hilos Cada hilo es un flujo de ejecución independiente Tiene su propio contador de programa Todos acceden al mismo espacio de memoria Necesidad de sincronizar cuando se accede concurrentemente a los recursos Existen estructuras de datos sincronizadas (ej, Vector) y sincronizar (ej, Array. List)

Creación de Hilos Se pueden crear de dos formas: Heredando de Thread Problema: No

Creación de Hilos Se pueden crear de dos formas: Heredando de Thread Problema: No hay herencia múltiple en Java Implementando Runnable Debemos crear sólo los hilos necesarios Dar respuesta a más de un evento simultáneamente Permitir que la aplicación responda mientras está ocupada Aprovechar máquinas con varios procesadores

Heredar de Thread public class Mi. Hilo extends Thread { public void Heredar run()

Heredar de Thread public class Mi. Hilo extends Thread { public void Heredar run() {de Thread y sobrecargar run( ) // Codigo de la tarea a ejecutar en el hilo } } Instanciar el hilo Thread t = new Thread(new Mi. Hilo()); t. start();

Implementar Runnable public class Mi. Hilo implements Runnable { public Implementar Runnable void run()

Implementar Runnable public class Mi. Hilo implements Runnable { public Implementar Runnable void run() { // Codigo de la tarea a ejecutar en el hilo } } Instanciar el hilo Thread t = new Thread(new Mi. Hilo()); t. start();

Ciclo de vida de los hilos ▪ El hilo será no ejecutable cuando: Se

Ciclo de vida de los hilos ▪ El hilo será no ejecutable cuando: Se encuentre durmiendo (llamando a sleep) Se encuentre bloqueado (con wait) Se encuentre bloqueado en una petición de E/S

Scheduler ▪ El scheduler decide qué hilo ejecutable ocupa el procesador en cada instante

Scheduler ▪ El scheduler decide qué hilo ejecutable ocupa el procesador en cada instante ▪ Se sacará un hilo del procesador cuando: Se fuerce la salida (llamando a yield) Un hilo de mayor prioridad se haga ejecutable Se agote el quantum del hilo ▪ Establecemos la prioridad con t. set. Priority(prioridad); La prioridad es un valor entero entre Thread. MIN_PRIORITY y Thread. MAX_PRIORITY

Concurrencia y sección crítica ▪ Cuando varios hilos acceden a un mismo recurso pueden

Concurrencia y sección crítica ▪ Cuando varios hilos acceden a un mismo recurso pueden producirse problemas de concurrencia ▪ Sección crítica: Trozo del código que puede producir problemas de concurrencia ▪ Debemos sincronizar el acceso a estos recursos Este código no debe ser ejecutado por más de un hilo simultáneamente ▪ Todo objeto Java (Object) tiene una variable cerrojo que se utiliza para indicar si ya hay un hilo en la sección crítica Los bloques de código synchronized utilizarán este cerrojo para evitar que los ejecute más de un hilo

Bloques sincronizados Para sincronizar un bloque de código podemos indicarle el objeto cuyo cerrojo

Bloques sincronizados Para sincronizar un bloque de código podemos indicarle el objeto cuyo cerrojo utilizaremos. El cerrojo (lock) se adquiere al inicio de la sección crítica y se libera al final de ésta Otro hilo no podrá adquirir ese mismo cerrojo al mismo tiempo synchronized(algun_objeto) { // Código sección crítica }

Métodos sincronizados Sincronzar un método o una sección de código public synchronized void seccion_critica()

Métodos sincronizados Sincronzar un método o una sección de código public synchronized void seccion_critica() { // Codigo } Se utiliza el cerrojo del objeto en el que se definen (cerrojo implícito) Se podrán ejecutar por un sólo hilo en un instante dado.

Uso de la sincronización ▪ Deberemos utilizar la sincronización sólo cuando sea necesario, ya

Uso de la sincronización ▪ Deberemos utilizar la sincronización sólo cuando sea necesario, ya que reduce la eficiencia ▪ No sincronizar métodos que contienen un gran número de operaciones que no necesitan sincronización Reorganizar en varios métodos ▪ No sincronizar clases que proporcionen datos fundamentales Dejar que el usuario decida cuando sincronizarlas en sus propias clases

Sincronización reentrante La sincronización en Java es “reentrante” porque un lock puede ser adquirido

Sincronización reentrante La sincronización en Java es “reentrante” porque un lock puede ser adquirido varias veces por un mismo hilo. Es decir, en el mismo hilo, una sección sincronizada puede contener a otra y esto no produce un bloqueo a pesar de que las dos adquieren el lock del objeto this: class Reentrant { public synchronized void a() b(); System. out. println(" } public synchronized void b() System. out. println(" } } { estoy en a() "); { estoy en b() ");

Dependencia de hilos Podemos esperar a que un hilo haya acabado de ejecutarse para

Dependencia de hilos Podemos esperar a que un hilo haya acabado de ejecutarse para poder continuar otro hilo Para ello bloquearemos el hilo actual que debe esperar a otro hilo t con: t. join();

Bloqueo de hilos Si el hilo va a esperar a que suceda un evento

Bloqueo de hilos Si el hilo va a esperar a que suceda un evento (por ejemplo, terminar una E/S), hay que bloquearlo para que no ocupe el procesador: wait(); Cuando suceda el evento debemos desbloquearlo desde otro hilo con: notify(); Ambos métodos deben ser invocados desde métodos sincronizados

Bloques vigilados En lugar de esperar iterativamente (que ocupa la CPU): public void bloque.

Bloques vigilados En lugar de esperar iterativamente (que ocupa la CPU): public void bloque. Vigilado() { // No hacerlo así! while(!condicion) {} // Se detiene aquí, //comprobando iterativamente la condición System. out. println("La condición se ha cumplido"); } Bloquear el hilo y esperar una notificación por parte de otro. public synchronized bloque. Vigilado() { while(!condicion) { try { wait(); // desocupa la CPU } catch (Interrupted. Exception e) {} } System. out. println("La condición se ha cumplido"); }

Ejemplo: productor/consumidor El productor produce si el buffer no está lleno, y si no

Ejemplo: productor/consumidor El productor produce si el buffer no está lleno, y si no debe esperar El consumidor consume si el buffer no está vacío, y si no debe esperar

Productor import java. util. Random; public class Producer implements Runnable { private Drop drop;

Productor import java. util. Random; public class Producer implements Runnable { private Drop drop; public Producer(Drop drop) { this. drop = drop; } public void run() { String important. Info[] = { "Mares eat oats", "Does eat oats", "Little lambs eat ivy", "A kid will eat ivy too" }; Random random = new Random(); for (int i = 0; i < important. Info. length; i++) { drop. put(important. Info[i]); try { Thread. sleep(random. next. Int(5000)); } catch (Interrupted. Exception e) {} } drop. put("DONE"); } }

Consumidor import java. util. Random; public class Producer implements Runnable { private Drop drop;

Consumidor import java. util. Random; public class Producer implements Runnable { private Drop drop; public Producer(Drop drop) { this. drop = drop; } public void run() { String important. Info[] = { "Mares eat oats", "Does eat oats", "Little lambs eat ivy", "A kid will eat ivy too" }; Random random = new Random(); for (int i = 0; i < important. Info. length; i++) { drop. put(important. Info[i]); try { Thread. sleep(random. next. Int(5000)); } catch (Interrupted. Exception e) {} } drop. put("DONE"); } }

//. . . public synchronized void put(String message) { // Wait until message has

//. . . public synchronized void put(String message) { // Wait until message has // been retrieved. while (!empty) { try { wait(); } catch (Interrupted. Exception e) {} } // Toggle status. empty = false; // Store message. this. message = message; // Notify consumer that status // has changed. notify. All(); } Recurso public class Drop { // Message sent from producer // to consumer. private String message; // True if consumer should wait // for producer to send message, // false if producer should wait for // consumer to retrieve message. private boolean empty = true; public synchronized String take() { // Wait until message is // available. while (empty) { try { wait(); } catch (Interrupted. Exception e) {} } // Toggle status. empty = true; // Notify producer that // status has changed. notify. All(); return message; } //. . . } //Main class: public class Producer. Consumer. Example { public static void main(String[] args) { Drop drop = new Drop(); (new Thread(new Producer(drop))). start(); (new Thread(new Consumer(drop))). start(); } }

Interbloqueos Deadlock: hilo A queda a la espera de que B lo desbloquee, a

Interbloqueos Deadlock: hilo A queda a la espera de que B lo desbloquee, a la vez que B queda a la espera de que A lo desbloquee: se interbloquean sin usar CPU Livelock: hilo A realiza acción que causa que B realice otra acción que a su vez vuelve a causar la acción de A: se interbloquean ocupando la CPU Stravation (inanición): otros hilos “hambrientos” ocupan el recurso (o CPU) que nuestro hilo necesita para seguir funcionando

Mecanismos de alto nivel Implementaciones que proporciona Java para facilitar la programación concurrencia –

Mecanismos de alto nivel Implementaciones que proporciona Java para facilitar la programación concurrencia – – – Interfaz Lock Colecciones concurrentes Variables atómicas Ejecutores y pools Otros muchos en el paquete java. util. concurrent

La interfaz Lock En lugar de synchronized: synchronized(this){ // acceder al recurso } Adquirir

La interfaz Lock En lugar de synchronized: synchronized(this){ // acceder al recurso } Adquirir un objeto Lock y después liberarlo Lock l =. . . ; l. lock(); try { // acceder al recurso protegido por l } finally { l. unlock(); }

La interfaz Lock Añade algunos métodos más versátiles – – – try. Lock( )

La interfaz Lock Añade algunos métodos más versátiles – – – try. Lock( ) : rechaza darnos el lock si éste no está disponible en el instante o bien tras un tiempo de espera especificado. Permite evitar deadlocks. lock. Interruptibly( ) : rechaza darnos el lock si otro hilo envía una interrupción antes de que el lock haya sido adquirido Da soporte a un mecanismo de wait/notify a través de objetos Condition que dejarían el hilo a la espera de que se cumpla la condición

Lock y Condition class Buffer. Limitado { final Lock lock = new Reentrant. Lock();

Lock y Condition class Buffer. Limitado { final Lock lock = new Reentrant. Lock(); //Dos condiciones para notificar sólo a los hilos //que deban hacer put o take, respectivamente final Condition not. Full = lock. new. Condition(); final Condition not. Empty = lock. new. Condition(); final Object[] items = new Object[100]; int putptr, takeptr, count; public void put(Object x) throws Interrupted. Exception { lock(); try { while (count == items. length) not. Full. await(); items[putptr] = x; if (++putptr == items. length) putptr = 0; ++count; not. Empty. signal(); } finally { lock. unlock(); } } public Object take() throws Interrupted. Exception { lock(); try { while (count == 0) not. Empty. await(); Object x = items[takeptr]; if (++takeptr == items. length) takeptr = 0; --count; not. Full. signal(); return x; } finally { lock. unlock(); } } }

Colecciones concurrentes La colección Vector garantiza el acceso sincronizado El paquete java. util. concurrent

Colecciones concurrentes La colección Vector garantiza el acceso sincronizado El paquete java. util. concurrent contiene colecciones con un soporte más avanzado para concurrencia – Blocking. Queue: FIFO con tiempo de espera máximo cuando añadimos y no cabe, o quitamos y no hay. – Concurrent. Map: subinterfaz de Map que define operaciones atómicas útiles (quitar una clave valor sólo si la clave está presente, etc). – Concurrent. Navigable. Map para coincidencias aproximadas

Variables atómicas Para no tener que sincronizar el acceso a variables, contamos con versiones

Variables atómicas Para no tener que sincronizar el acceso a variables, contamos con versiones atómicas de éstas: – Atomic. Boolean – Atomic. Integer. Array – Atomic. Integer. Field. Updater<T> – Atomic. Long. Array – Atomic. Long. Field. Updater<T> – Atomic. Markable. Reference<V> – Atomic. Reference. Array<E> – Atomic. Reference. Field. Updater<T, V> – Atomic. Stamped. Reference<V>

Variables atómicas Ejemplo: synchronized / variable atómica import java. util. concurrent. atomic. Atomic. Integer;

Variables atómicas Ejemplo: synchronized / variable atómica import java. util. concurrent. atomic. Atomic. Integer; class Contador. Sincronizado { private int c = 0; class Contador. Atomic { private Atomic. Integer c = new Atomic. Integer(0); public synchronized void increment() { c++; } public synchronized void decrement() { -; } public void increment() { c. increment. And. Get(); } c- public void decrement() { c. decrement. And. Get(); } public synchronized int value() { return c; } } public int value() { return c. get(); } }

Ejecutores Se separa la gestión de la ejecución de los hilos en clases especializadas

Ejecutores Se separa la gestión de la ejecución de los hilos en clases especializadas Interfaz Executor: obliga a implementar el método execute(Runnable r) En lugar de iniciar el hilo con (new Thread(r)). start( ); lo iniciaremos con e. execute(r); teniendo: Runnable r; Executor e;

Executor. Service Subinterfaz de Executor Añade el método Future submit( objeto ) que acepta

Executor. Service Subinterfaz de Executor Añade el método Future submit( objeto ) que acepta objetos Runnable y Callable, que permiten devolver un valor al finalizar la tarea. submit( ) devuelve objetos Future que permiten obtener el estado de la tarea a ejecutar y devuelven un resultado en el caso de Callable.

Scheduled. Executor. Service Subinterfaz de Executor. Service Añade el método schedule( ) que ejecuta

Scheduled. Executor. Service Subinterfaz de Executor. Service Añade el método schedule( ) que ejecuta un Runnable o Callable después de un tiempo especificado También añade schedule. At. Fixed. Rate( ) y schedule. With. Fixed. Delay( ) para tareas periódicas

Pools de hilos Uno o varios “worker thread” ejecutan los métodos run( ) de

Pools de hilos Uno o varios “worker thread” ejecutan los métodos run( ) de distintos Runnable / Callable, pero en el mismo hilo. Se ahorra la sobrecarga de creación y destrucción de hilos en la que interviene reserva y liberación de memoria Creación del pool – distintas maneras: – – Método estático new. Fixed. Thread. Pool(n) Instancia de Thread. Pool. Executor o de Scheduled. Thread. Pool. Executor.

Instancia de Thread. Pool. Executor //Al principio del fichero: //import java. util. concurrent. *;

Instancia de Thread. Pool. Executor //Al principio del fichero: //import java. util. concurrent. *; //import java. util. *; int pool. Size = 2; int max. Pool. Size = 2; long keep. Alive. Time = 10; final Array. Blocking. Queue<Runnable> queue = new Array. Blocking. Queue<Runnable>(5); Thread. Pool. Executor thread. Pool = new. Thread. Pool. Executor(pool. Size, max. Pool. Size, keep. Alive. Time, Time. Unit. SECONDS, queue); Runnable my. Tasks[3] =. . ; // y le asignamos tareas //Poner a ejecutar dos tareas y una quedará en cola: for(int i=0; i<3; i++){ thread. Pool. execute(task); System. out. println("Tareas: " + queue. size()); } //Encolar otra tarea más que declaramos aquí mismo: thread. Pool. execute( new Runnable() { public void run() { for (int i = 0; i < 10; i++) { try { System. out. println("i = " + i); Thread. sleep(1000); } catch (Interrupted. Exception ie){ } } }); } //Ejecuta las tareas queden pero ya no acepta nuevas: thread. Pool. shutdown();

Sobrecarga de Thread. Pool. Executor class Pausable. Thread. Pool. Executor extends Thread. Pool. Executor

Sobrecarga de Thread. Pool. Executor class Pausable. Thread. Pool. Executor extends Thread. Pool. Executor { //Método nuevo: public void pause() { pause. Lock. lock(); //Sección sincronizada try { is. Paused = true; } finally { pause. Lock. unlock(); } } private boolean is. Paused; private Reentrant. Lock pause. Lock = new Reentrant. Lock(); private Condition unpaused = pause. Lock. new. Condition(); //Sobrecargamos el método: protected void before. Execute(Thread t, Runnable r) { super. before. Execute(t, r); pause. Lock. lock(); //Sección sincronizada try { while (is. Paused) unpaused. await(); //Bloquearlo } catch (Interrupted. Exception ie) { t. interrupt(); } finally { pause. Lock. unlock(); } } //Nota: para pausar cada hilo el programador debe //implementar la lógica necesaria //Método nuevo: public void resume() { pause. Lock. lock(); //Sección sincronizada try { is. Paused = false; unpaused. signal. All(); //Desbloquea hilos bloqueados } finally { pause. Lock. unlock(); } } }

Lenguaje Java FIN

Lenguaje Java FIN