SlideShare una empresa de Scribd logo
1 de 38
Descargar para leer sin conexión
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
TEMARIO DE CURSO
PROGRAMACIÓN JAVA SE
CAPÍTULO 21
JSE AVANZADO:
• ASSERTS (AFIRMACIONES)
• EXPRESIONES REGULARES
• PATRONES DE DISEÑO
• ANONIMOS
• LAMBDA
• LOGGER
Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional.
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Logging
๏ Cuando un programa está en entorno de producción, es muy útil tener un log donde se guarden los errores que se
producen, o mejor aun, todos los eventos que se van realizando en el programa, para poder hacer un seguimiento de
como se han ido ejecutando las cosas, para explicar por ejemplo, errores que se produzcan
๏ Hay muchas librerías y frameworks para este propósito, pero Java también lo permite con la clase Java Logging Api
๏ Debemos prepara primer el entorno de logging, y luego usarlo donde deseemos.
Logging
2
➡ Preparar el entorno de log (solo hace falta hacerlo una vez en cada proyecto):
‣ Crear un objeto de tipo Logger desde el cual enviaremos los mensajes
Los mensajes normalmente se envían a un fichero de texto (también se pueden enviar a la consola solamente)
Si se desea usar el mismo objeto Logger desde varias clases, se recomienda que sea de tipo static
‣ Crear un objeto FileHandler y agregarlo al Logger. Este tipo de handler enviara los mensajes al archivo que le
indiquemos.
‣ EL Logger escribe por defecto en formato XML (cada mensaje). Si deseamos que tenga otro formato (texto plano
por ejemplo) debemos crear un objeto SimpleFormatter y asociarlo al FileHandler
➡ Guardar mensajes en el fichero de log (se realizará cada vez que se desee registrar algo en el log)
‣ Se usa el método log() del Logger, con dos parámetros : tipo de mensaje, y mensaje en si
Cada entrada del log guama ademas automáticamente la fecha, hora, el nombre completo de la clase y el método y en el caso de mensajes de nivel grave
la linea de código donde se genero el reporte
‣ Para los tipos de mensaje se pueden usar estas constantes
- Level.INFO: Mostrar mensajes informativos
- Level.CONFIG: Mostrar mensajes de configuración
- Level.WARNING: Mostrar mensajes de alerta
- Level.SEVERE: Mostrar mensajes críticos
- Level.FINE: Mostrar mensajes de depuración de nivel 1
- Level.FINER: Mostrar mensajes de depuración de nivel 2
- Level.FINEST: Mostrar mensajes de depuración de nivel 3
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
๏ Ejemplo de Logger
3Logging
// Se crea un objeto Logger con un nombre
// Logger logger2 = Logger.getLogger("logDeMiClase");
// Sin embargo, es práctica habitual usar para el nombre del Logger
// el fully qualified name de cada una de las clases (si cada clase tiene su logging, claro).
Logger logger = Logger.getLogger(Miclaseactual.class.getName());
// Los handler (manejadores) indican donde mandar los mansajes, a consola o archivo
// Si no se indica handler, los mensajes van solo a consola
// Si no se indica un FileHandler, se envían los mensajes a un fichero (y a consola)
Handler fileHandler = new FileHandler("./ficheroDeLog.log", false);
// Un formateador indica como escribir los datos
// Si no se usa formatter, se escriben los mensajes en formato XML
// Si se desea un formato diferenrte, de debe usar un formateador, de los que existen o personalizado
// Este ejemplo simple de formateador escribe el mensaje como texto plano
SimpleFormatter simpleFormatter = new SimpleFormatter();
// Asi se asigna el formateador al FileHandler
fileHandler.setFormatter(simpleFormatter);
// Asi se asigna el FileHandler al Logge
logger.addHandler(fileHandler);
// Ahora ya Usamos los logger donde queramos
try {
logger.log(Level.INFO, "Se van a asignar valores ");
int x = 43;
int y = 0;
if (y == 0) {
logger.log(Level.WARNING, "Cuidado, puede que falle pues y es 0");
}
double p = x / y;
logger.log(Level.INFO, "valores ya asignados ");
} catch (Exception e) {
logger.log(Level.SEVERE, "ERROR, se ha producido un error");
logger.log(Level.SEVERE, e.getMessage());
}
// Logger super simple, se declara y solo envía mensajes a consola
public static Logger LOGGERSIMPLE = Logger.getLogger(Clases.class.getName());
LOGGERSIMPLE.log(Level.INFO, "Mensaje a la consola ");
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Asserts
๏ Asserts son “afirmaciones”, es decir, podemos comprobar en cualquier parte de un método una expresión y ver si una
afirmación (la expresión) es cierta. Si no lo es, se lanza un AssertionError, que detiene el programa. Cuidado, un
AssertionError NO es una excepción, es un Error (y además, Unchecked, por lo tanto, se podría intentar capturar,
pero como veremos, es justo lo que no queremos hacer)
๏ Ventajas:
๏ Forma de usar las Asserts:
assert unaExpresion : stringMensaje ;
๏ donde unaExpresion es cualquier expresión que devuelve un boolean. Cuando se ejecuta el código, al llegar al assert
se evalúa unaExpresion y si esta devuelve un false, Java lanza un AssertionError. El string stringMensaje es un String
que se manda al constructor del AssertionError, para ayudar a que se clarifique el problema que se ha detectado. Este
string es opcional (si no se usa, no se ponen tampoco los dos puntos)
๏ Los asserts se deben de utilizar para validar una variable o el valor retornado para alguna sentencia o método, no
deben usarse para programar funcionalidad de la aplicación
Afirmaciones (Asserts)
‣ Se usan para que el programa avise de las condiciones de la ejecución. Las Asserts no
afectan a la ejecución de un código, simplemente comprueban expresiones. Son por lo tanto
muy útiles en fase de pruebas y depuración de código.
‣ Las Asserts se pueden desactivar para que, aunque estén en el código, no se evaluen, con
lo que no molestan ni en tiempo de poner la aplicación en producción.
4
public class PruebasAssert{
public static void main(String[] args) {
int x=4;
assert x==5: "X no es igual a 5";
}
}
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Properties
๏ Properties es una clase heredera de HashTable. Se usa en muchas otras clases de Java (por ejemplo, es lo que
devuelve System.getProperties( ) cuando informa de los valores de las variables de entorno)
๏ Amén de otros métodos de los HashTable, tiene métodos propios para facilitar el alta y consulta de cualquier lista de
“propiedades”, sea propia o generada por otras clases
Properties
5
Properties valoresConexion = new Properties();
valoresConexion.put("ip", "localhost");
valoresConexion.put("puerto", "50001");
valoresConexion.put("usuario", "pepe");
valoresConexion.put("password", "12345");
String antiguoValor = (String) valoresConexion.setProperty("password", "98765");
System.out.println(antiguoValor);
String laip = valoresConexion.getProperty("ip");
System.out.println(laip);
String puerto = (String) valoresConexion.get("puerto");
System.out.println(puerto);
for(Object clave : valoresConexion.keySet()){
System.out.println("Clave-Valor es " + clave + " - " + valoresConexion.getProperty((String)clave) + ".");
}
Iterator it = valoresConexion.keySet().iterator();
while(it.hasNext()) {
String clave = (String) it.next();
System.out.println("la clave " + clave + " tiene valor " + valoresConexion.getProperty(clave) );
}
for(){
valoresConexion.put("passwordnumerica", 42352);
String antiguoValor = (String) valoresConexion.setProperty("password", "98765");
Se crea un objeto simple
de la clase Properties
como hereda de Map puedo añadir los elementos
ea la colección con un put sin problemas
También tiene un método propio setProperty(), que hace lo mismo que put, solo
que ademas devuelve el valor que hubiera ante de aplicar la clave-valor nueva
Para obtener una propiedad, usar el método getProperty(), o el clásico get() de los
Maps. Solo recordar que el get() devuelve un Object, necesita un casting
Para recorrer la colección, usar un foreach (los elementos de la colección
son Objects, cuidado), o recorrer con un iterator el conjunto de las claves de
la colección, y con cada clave, recoger su valor
Como no se define el tipo del valor puede ser lo que se quiera, pero es
peligroso usar algo que nos sea String…. De hecho, el método serProperty no
deja añadir valores que no sean String
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
Una expresión regular sirve para comprobar el formato de una cadena.
Se basa en definir un patrón y comprobar que la cadena cumpla las reglas de ese patron.
Algunos ejemplos de patrones pueden ser:
• para comprobar que la fecha leída cumple el patrón dd/mm/aaaa
• para comprobar que un NIF está formado por 8 cifras, un guión y una letra
• para comprobar que una dirección de correo electrónico es una dirección válida.
• para comprobar que una contraseña cumple unas determinadas condiciones.
• para comprobar que una URL es válida.
• para comprobar cuántas veces se repite dentro de la cadena una secuencia de caracteres determinada.
Para escribir el patrón (la expresión regular) se usan unos elementos con un formato específico: símbolos,
metacaracteres, cuantificadores…
Expresiones Regulares
Expresiones regulares
6
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Expresiones Regulares
Simbolos
Metacaracteres
CUIDADO
En Java como la expresión
regular es un String, se ha de
usar un doble  en vez de una
sola, para “escapar” la
siguiente barra, esto es, no
usar d, sino d
Concatenación . El patron “AB” cumple si el String contiene A seguida de B
. Un punto indica cualquier carácter
^ El símbolo ^ indica el principio del String.
El patron “^ expresion” cumple si el String contiene expresión al principio.
$ El símbolo $ indica el final del String.
El patron “expresion $” cumple si el String contiene expresión al final
[ ] Los corchetes representan una definición de conjunto.
El patron “[abc]” cumple si el String contiene las letras a ó b ó c.
El patron “[abc][12]” cumple si el String contiene las letras a ó b ó c seguidas de 1 ó 2
^ en [ ] El símbolo ^ dentro de los corchetes indica negación.
El patron “[^abc]” cumple si el String contiene cualquier carácter excepto a ó b ó c.
- Rango.
El patron “[a-z1-9]” cumple si el String contiene letras minúsculas desde la a hasta la z (ambas incluidas) y los
dígitos desde el 1 hasta el 9 (ambos incluidos)
| El carácter | es un OR.
El patron “A|B” cumple si el String contiene A ó B
( ) Agrupar (como en matematicas) para aplicar modificadores o cuantificadores
d Dígito. Equivale a [0-9]
D No dígito. Equivale a [^0-9]
s Espacio en blanco. Equivale a [ tnx0brf
S No espacio en blanco. Equivale a [^s
w Una letra mayúscula o minúscula, un dígito o el carácter _ Equivale a [a-zA-Z0-9_]
W Equivale a [^w]
b Límite de una palabra.
7
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
CUIDADO: Si se quiere hacer referencia explicita en el patrón a un carácter que es un cuantificador, o un símbolo,
ha de usarse la  (en java ) para “evitar” que evalúe el carácter y lo tome simplemente como tal: el patrón (.)*
indica un punto 0 o mas veces
Para usar expresiones regulares en Java se usan las clases Pattern y Matcher y la excepción
PatternSyntaxException (paquete java.util.regex). Para comprobaciones también se puede usar String
• Clase Pattern: Contiene el método compile(String regex) que recibe como parámetro la expresión regular y
devuelve un objeto de la clase Pattern, que representa la expresión regular ya “preparada”.
• La clase Matcher: Esta clase compara el String y la expresión regular. Con su método matches() que recibe
como parámetro el String a validar y devuelve true si coincide con el patrón.
• La clase String también tiene un método matches() para evaluar directamente un patrón sobre una cadena
Expresiones Regulares
Cuantificadores
{X} Indica que lo que va justo antes de las llaves se repite X veces
{X,Y} Indica que lo que va justo antes de las llaves se repite mínimo X veces y máximo Y veces. También podemos
poner {X,} indicando que se repite un mínimo de X veces sin límite máximo.
* Indica 0 ó más veces. Equivale a {0,}
+ Indica 1 ó más veces. Equivale a {1,}
? Indica 0 ó 1 veces. Equivale a {0,1}
8
String cadena = "abc";
if (cadena.matches("^abc.*"))
System.out.println("SI cumple patron");
else
System.out.println("NO cumple patron");
String cadena = "abc";
Pattern pat = Pattern.compile("abc");
Matcher mat = pat.matcher(cadena);
if (mat.matches())
System.out.println("SI cumple patron");
else
System.out.println("NO cumple patron");
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Expresiones Regulares
EJEMPLOS de expresiones regulares
Comprobar si el String cadena comienza por “abc” comienzodelinea cualquiercaracter muchasveces
^ abc . *
Comprobar si el String cadena contiene exactamente “abc”
Comprobar si el String cadena contiene “abc”
Comprobar si el String cadena comienza por “abc” ó “Abc”
cualquiercaracter muchasveces cualquiercaracter muchasveces
. * abc . *
Comprobar si cadena está formado por un mínimo de 5 letras mayúsculas o minúsculas y un máximo de 10
9
String cadena = "abc";
Pattern pat = Pattern.compile("abc");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "adbdc";
Pattern pat = Pattern.compile("abc");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "vavasvvccsascca";
Pattern pat = Pattern.compile("[a-zA-Z]{5,10}");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "abc";
Pattern pat = Pattern.compile(".*abc.*");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "adbc";
Pattern pat = Pattern.compile("^[aA]bc.*");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "Abc";
Pattern pat = Pattern.compile(“^[aA]bc.*”);
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "aaffabc";
Pattern pat = Pattern.compile("^abc.*");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "abc";
Pattern pat = Pattern.compile("^abc.*");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "csdcWWxx";
Pattern pat = Pattern.compile("[a-zA-Z]{5,10}");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println(“NO cumple");
String cadena = "ddcabdc";
Pattern pat = Pattern.compile(".*abc.*");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
Comprobar si el String cadena es una direccion de mail valida
Explicación de este último ejemplo:
Expresiones Regulares
Comprobar si el String cadena solo contienen los caracteres a ó b
Comprobar si el String cadena contiene un 1 y ese 1 no está seguido por un 2
[w-]+ Inicio del email
El signo + indica que debe aparecer uno o más de los caracteres entre corchetes: w indica caracteres de la
A a la Z tanto mayúsculas como minúsculas, dígitos del 0 al 9 y el carácter _ :Carácter – En lugar de usar
w podemos escribir el rango de caracteres con lo que esta expresión quedaría así: [A-Za-z0-9-_]+
(.[w-]+)* El * indica que este grupo puede aparecer cero o más veces. El email puede contener de forma opcional un
punto seguido de uno o más de los caracteres entre corchetes.
@ A continuación debe contener el carácter @
[A-Za-z0-9]+ Después de la @ el email debe contener uno o más de los caracteres que aparecen entre los corchetes
(.[A-Za-z0-9]+)* Seguido (opcional, 0 ó más veces) de un punto y 1 ó más de los caracteres entre corchetes
(.[A-Za-z]{2,}) Seguido de un punto y al menos 2 de los caracteres que aparecen entre corchetes (final del email)
10
String cadena = “aababa.bbaba@dalsd.acsa.com“;
Pattern pat = Pattern.compile("^[w-]+(.[w-]+)*@[A-Za-z0-9]+(.[A-Za-z0-9]+)*(.[A-Za-z]{2,})$");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "aaffabc";
Pattern pat = Pattern.compile(".*1(?!2).*");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "aabababbaba";
Pattern pat = Pattern.compile(".*1(?!2).*");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "aaffabc";
Pattern pat = Pattern.compile("(a|b)+");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
String cadena = "aabababbaba";
Pattern pat = Pattern.compile("(a|b)+");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Expresiones Regulares
Comprobar si el String cadena contiene un numero de teléfono español
11
String cadena = "+34924221133";
Pattern pat = Pattern.compile("/+34 9[0-9]{1,2} [0-9]{7}/");
Matcher mat = pat.matcher(cadena);
if(mat.matches()) System.out.println("SI cumple");
else System.out.println("NO cumple");
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
• El patrón factoría consiste en construir una estructura (una clase Factoría) que ofrezca métodos para crear objetos de otra
clase X. El objeto es “esconder” la clase X al público, a quien no le interesa ni cómo trabaja X ni cómo se implementa.
• El patrón se ve mejor con una estructura de herencia, y mejor aun con un ejemplo.
Patrones de diseño: Factoría (I)
Patrón factoría
2) Creamos las clases que implementan la interfaz. En este caso son tres tipos de
perros que actúan de forma diferente
12
class Caniche implements IPerro
{
public void ladrar()
{
System.out.println("El caniche dice "guau guau"");
}
}
class Doberman implements IPerro
{
public void ladrar()
{
System.out.println(""El Doberman dice "GUAUUU GUAUUU""");
}
}
class Bulldog implements IPerro
{
public void ladrar()
{
System.out.println(""El Bulldog dice "No me pisoteeis mas!!"");
}
}
interface IPerro
{
public void ladrar ();
}
1) Creamos una interfaz, que define el
contrato que han de cumplir las clases
que la implementen:
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
Ventajas:
• La factoría no dice que lo que devuelve es un Doberman, Caniche o Bulldog. Simplemente devuelve algo que implemente
la interfaz IPerro
• En el main solo le decimos a la factoría qué queremos, y la clase factoría decide qué subclase ha de crear y devolver al
main. No se sabe qué clase ha creado el perro que recibimos, ni siquiera como se llama.
• Por supuesto, también podemos hacer que el método getter de la factoría reciba directamente el nombre del perro. Aun y
así, no se sabe qué clase o qué componente java está desarrollado para “construir” el perro solicitado, pues el nombre no es
mas que una “característica” que igualmente usa la factoría para elegir lo que devuelve
• El criterio de selección en este caso es sencillo, pero puede ser muy complejo, por ejemplo con más información de entrada
al getter y más lógica de selección de objeto a devolver.
3) Creamos ahora la clase Factoría, la esencia del patrón. Esta
factoría define un método getxx ( casi como un getter normal)
que devuelve un objeto de tipo Perro, esto es, el tipo “base” de
la herencia. Para “pedir” el perro, espera por argumento la
información del uso se le va a dar al perro, su oficio:
4) Finalmente, vemos la factoría en acción, Los
perros se crean usando la factoría, y pidiéndolos por
su oficio.
public class Main {
public static void main(String[] args) {
// crear un perro para ancianos
IPerro miPerro;
miPerro= PerroFactory.getPerro("ancianos");
miPerro.ladrar();
// crear un perro para defensa
miPerro = PerroFactory.getPerro("defensa");
miPerro.ladrar();
// crear un perro para niños
miPerro = PerroFactory.getPerro("niños");
miPerro.ladrar();
}
}
// Clase Factoria para Perros
class PerroFactory
{
public static IPerro getPerro(String oficio)
{
if ( oficio.equals("ancianos"))
return new Caniche();
else if ( oficio.equals("defensa") )
return new Doberman();
else if ( oficio.equals("niños") )
return new Bulldog();
return null;
}
}
13Patrones de diseño: Factoría (II)
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
• El patrón Singleton consiste en garantizar que una clase solo tenga una instancia y proporcionar un punto de
acceso global a ella. Por ejemplo, suele ser muy utilizado para las conexiones a bases de datos.
• Por lo tanto, se pueden crear varios objetos de la clase, pero todos apuntan a una UNICA instancia de la
misma.
• Se implementa haciendo privado el constructor de la clase y creando (en la propia clase) un método que crea
una instancia del objeto si este no existe, o que devuelve la instancia ya creada si ya existe
• Veamos un ejemplo de este patrón. La clase ClaseConInstanciaUnica tiene un constructor privado, y un
método llamado 'getUnicaInstancia()' que será el encargado de crear una instancia de esta clase si no se ha
creado todavía:
Patrón Singleton
class ClaseConInstanciaUnica{
private String identificador;
private static ClaseConInstanciaUnica unicaInstancia;
// El constructor es privado, solo accesible desde el metodo getUnicaInstancia()
// Asi además no se permite que se genere un constructor por defecto.
private ClaseConInstanciaUnica(String identificador){
this.identificador = identificador;
}
// El metodo getUnicaInstancia() devuelve una instancia de esta clase.
// Si no existia la instancia, la crea y devuelve, si ya existia, devuelve esa misma
public static ClaseConInstanciaUnica getUnicaInstancia(String identificador){
if (unicaInstancia == null){
unicaInstancia = new ClaseConInstanciaUnica(identificador);
System.out.println("Se ha creado una nueva instancia y se devuelve la referencia ");
} else{
System.out.println("No se crea una nueva instancia, se devuelve la referencia " +
"de la instancia ya existente");
}
return unicaInstancia;
}
}
El patrón Singleton puede dar problemas con multitarea, por lo que se deberia usar syncronized para evitarlos
14Patrones de diseño: Singleton
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 15
๏ El patrón de diseño Observer define una dependencia del tipo uno a muchos entre objetos, de manera que cuando un
objeto s cambia su estado, notifica este cambio a otros objetos.
๏ Este patrón también se conoce como el patrón de publicación-inscripción o modelo-patrón.
๏ Se compone básicamente de:
‣ una clase (a la que se suele llamar sujeto) que es observada
‣ otros objetos de otras clases (llamadas observadores) que esperan noticias de la observada
๏ La clase Sujeto contiene atributos mediante los cuales cualquier objeto observador o vista se puede suscribir a él
pasándole una referencia a sí mismo, y hace llamadas de “publicación” de cambios cuando le interesa
Clase
Observada
Clase
Observer
Clase
Observer
Clase
Observer
Se envían mensajes cuando algo
ocurre en la clase Observada
mensaje
mensaje
mensaje
Patrón Observer
Patrones de diseño: Observer (I)
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 16
public class Producto extends Observable {
private String nombre;
private int precio;
private Observer observer;
public Producto() {
}
@Override
public void addObserver(Observer observer) {
this.observer = observer;
}
public int getPrecio() {
return precio;
}
public void setPrecio(int precio) {
this.precio = precio;
notifyObservers();
}
public void enRebajas(int porcentaje) {
this.precio = precio - (precio/100 *porcentaje);
notifyObservers();
}
@Override
public void notifyObservers() {
if (observer != null)
observer.update(this, "Producto-Cambio de precio");
}
}
Patron Observer: el Observable
๏ El Observable es la clase que es observada, la que notifica a las demás que ha sufrido cambios
La clase debe HEREDAR de Observable
La clase debe tener un método addObserver(), que
recibe un objeto de tipo Observer, que será cada uno
de los observadores que están mirando esta clase.
El observador recibido lo guarda en un atributo de tipo
Observer, o si se desea muchos observadores, en una
colección de Observer
Cuando se produce en la clase observada
alguna situación que desee compartir con los
observadores, se hace en ese momento una
invocación al método notifyObservers()
Finalmente, se escribe el método
notifyObservers(), que usa el objeto (u objetos,
si es una colección) de Observers y les ejecuta
el método update().
En dicho método envía una copia de la la propia
clase (el this inicial) y algún contenido que
identifique el cambio.
El contenido es un Object, así que puede ser
tanto un simple String, como cualquier objeto
más complejo.
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 17
public class Cotilla implements Observer {
private String nombre;
// Método que se ejecuta cuando se producen cambios
@Override
public void update(Observable o, Object arg) {
if (arg.equals("Soy un producto y hay cambio en stock")) {
System.out.println("Soy el cotilla, y ya se que el producto ha cambiado de precio!! ");
Producto pp = (Producto)o;
System.out.println("y el nuevo precio es …"+pp.getPrecio());
}
if (arg.equals("Soy una fabrica y hay cambio en unidades vendidas")) {
Fabrica ff = (Fabrica)o;
System.out.println("jeje, en la fabrica hay “+ff.getUnidadesVendidas()+" unidades....");
}
}
}
Patron Observer: el Observer
๏ El Observer es la clase que observa a la clase Observable vista antes. Debe tener un método update() que es
invocado en cada cambio de la clase Observable
๏ Se trata de una clase normal, puede tener los atributos y métodos que necesite, en este ejemplo tiene un simple
atributo nombre, que ni siquiera se usa :-)
En la clase Observer, que esta observando lo que pasa en la Observable vista antes, debe existir un método update()
El método recibe dos parámetros:
• El objeto de Observable, que trae una copia del objeto observado. Sirve para saber DONDE se ha producido el mensaje. Notar que
se hace un casting para convertirlo en el tipo de la clase que se desea evaluar: Producto pp = (Producto)o;
• Un objeto generico (llamado aqui args) que trae el “mensaje” desde la clase Observada. Recordar que se trata de un Object, así que
puede ser tanto un simple String, como cualquier objeto más complejo. Sirve para saber QUE mensaje se ha producido
Si se desea saber qué clase ha producido el mensaje, también se puede preguntar por su tipo con una instrucción como :
La clase debe IMPLEMENTAR de Observer
if(o instanceof Producto){
.......
}
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 18Patron Decorador (Decorator) (I)
๏ El patrón de diseño Decorador asigna responsabilidades adicionales a un objeto dinámicamente, proporcionando una
alternativa flexible a la herencia
๏ El ejemplo más claro del patrón dentro del propio JSE de Java es el paquete IO de entrada/salida. En el uso habitual
de estas clases, unas recubren a otras siguiendo el patrón de diseño Decorador de tal modo que se van añadiendo
nuevas funcionalidad a la clase original con cada nuevo recubrimiento.
๏ Veámoslo con un ejemplo paso a paso:
Patrón Decorador
//--------------------------------- VEHICULO
abstract class Vehiculo {
private float precio;
public Vehiculo(float precio) {
this.precio = precio;
}
public float getPrecio() {
return precio;
}
public abstract String descripcion();
}
//--------------------------------- UTILITARIO
class Utilitario extends Vehiculo {
public Utilitario(float precio) {
super(precio);
}
@Override
public String descripcion() {
return "Vehículo utilitario";
}
}
//--------------------------------- FAMILIAR
class Familiar extends Vehiculo {
public Familiar(float precio) {
super(precio);
}
@Override
public String descripcion() {
return "Vehículo familiar";
}
}
‣ Queremos crear una serie de clases que representen diferentes
vehículos (familiar, utilitario, todoterreno), y calcular el precio de
cada uno, según los complementos que lleve instalado cada
vehículo (airbag, techo solar, xenon, etc..)
‣ Partimos de entrada de una herencia de clases que tiene por ahora
como único valor fijo el precio final del coche
‣ El problema viene ahora, cuando los complementos de cada tipo de
coche tienen ademas un coste distinto (no es lo mismo el coste de
airbag de un utilitario que en un todoterreno….)
‣ Por lo tanto, lo que nos pide el cuerpo en primera instancia es crear
atributos de cada complemento en la clase madre, pero darles
valores uno a uno en cada subclase
public class PatronDecorador {
public static void main(String[] args) {
Utilitario u = new Utilitario(12000);
Familiar f = new Familiar(24000);
System.out.println(u.descripcion());
System.out.println(f.descripcion());
}
}
consola
Vehículo utilitario
Vehículo familiar
( Ejemplos extraídos de Oscar Belmonte, de Universitat Jaume I )
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 19
‣ Por lo tanto, lo que nos pide el cuerpo en primera instancia es crear atributos de cada complemento en la clase madre,
pero darles valores uno a uno en cada subclase. Claro que esto puede ser tedioso si hay muchos complementos… y
además, si en el futuro se añaden complementos a un tipo de coche, hemos de cambiar las clases creadas
‣ Lo que pretende Decorador es que creemos un estructura con una definición básica, y luego, envolvamos dicha
definición con otras clases que vayan complementando, mejorando, “decorando” la clase básica inicial
‣ Así que vamos a tomar nuestra clase Vehículo como básica, y vamos a crear los “decoradores” que la completen
‣ Primera aproximación; crear clases por cada complemento existente, que hereden de Vehículo también (para que sean
vehículos mejorados) y hacer que dichas clases tengan como atributo un objeto Vehículo (que será el “Vehiculo original”
y al que vamos a mejorar):
class VehiculoConAirbag extends Vehiculo { // Lo que se crea con esta clase sigue siendo un Vehiculo
private Vehiculo vehiculo; // Es es el objeto que va a decorar al vehículo original
public VehiculoConAirbag(Vehiculo vehiculo, float precioExtra) {
super(precioExtra); // Pasamos a la madre el precio del extra para que lo guarde
this.vehiculo = vehiculo; // Recibimos aqui una referencia del Vehiculo que vamos a decorar
}
@Override
public String descripcion() {
return vehiculo.descripcion() + // La descripcion del vehiculo decorado es la del vehículo original
", con airbag"; // mas la descripcion de lo que se decora
}
@Override
public float getPrecio() {
return vehiculo.getPrecio() + // El precio del vehiculo con su decorado es el del vehículo original
super.getPrecio(); // mas el precio extra que se añade ahora (y lo tenia la madre).
}
}
//------------------------------- primera aproximacion
Vehiculo vehiculo = new Utilitario(12000);
vehiculo = new VehiculoConAirbag(vehiculo, 840);
System.out.println(vehiculo.getPrecio());
Así se crea un nuevo vehículo, que recibe como argumento el
vehículo original, y lo decora añadiendo funcionalidad. En nuevo
vehículo creado lo almaceno en la referencia del …vehículo original
Crear vehículo original
consola
12840
Patron Decorador (Decorator) (II)
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 20
class VehiculoConAirbag extends Vehiculo {
private Vehiculo vehiculo;
public VehiculoConAirbag(Vehiculo vehiculo,
float precioExtra) {
super(precioExtra);
this.vehiculo = vehiculo;
}
@Override
public String descripcion() {
return vehiculo.descripcion() +
", con airbag";
}
@Override
public float getPrecio() {
return vehiculo.getPrecio() +
super.getPrecio();
}
}
class VehiculoConXenon extends Vehiculo {
private Vehiculo vehiculo;
public VehiculoConXenon(Vehiculo vehiculo,
float precioExtra) {
super(precioExtra);
this.vehiculo = vehiculo;
}
@Override
public String descripcion() {
return vehiculo.descripcion() +
", con xenon";
}
@Override
public float getPrecio() {
return vehiculo.getPrecio() +
super.getPrecio();
}
}
‣ Cuando nos ponemos a hacer nuevas clases para más complementos, nos damos cuenta de que todas son casi iguales
entre si, así que sacamos “factor común”, y creamos una superclase para los complementos y subclases para cada uno:
abstract class Extra extends Vehiculo {
private Vehiculo vehiculo;
public Extra(Vehiculo vehiculo, float precioExtra) {
super(precioExtra);
this.vehiculo = vehiculo;
}
@Override
public float getPrecio() {
return vehiculo.getPrecio() + super.getPrecio();
}
@Override
public String descripcion() {
return vehiculo.descripcion();
}
}
class VehiculoConXenon extends Extra {
public VehiculoConXenon(Vehiculo vehiculo, float precioExtra) {
super(vehiculo, precioExtra);
}
@Override
public String descripcion() {
return super.descripcion() + ", con pintura metalizada";
}
}
class VehiculoConAirbag extends Extra {
public VehiculoConAirbag(Vehiculo vehiculo, float precioExtra) {
super(vehiculo, precioExtra);
}
@Override
public String descripcion() {
return super.descripcion() + ", con aire acondicionado";
}
}
Demasiado
iguales,
haremos mejor
una estructura
de herencia
Patron Decorador (Decorator) (III)
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 21
//------------------------------- aproximacion final
Vehiculo vehiculo = new Utilitario(12000);
vehiculo = new VehiculoConAirbag(vehiculo, 840);
System.out.println(vehiculo.descripcion());
System.out.println(vehiculo.getPrecio());
vehiculo = new VehiculoConXenon(vehiculo, 300);
System.out.println(vehiculo.descripcion());
System.out.println(vehiculo.getPrecio());
‣ Solo con la creación de la nueva estructura de herencia, se pueden probar los mismos objetos de la primera
aproximación, y funcionan perfectamente
‣ Para el futuro, si se desea añadir mas complementos al coche, solo necesitamos crear la clase del complemento
correspondiente !!
consola
Vehículo utilitario, con airbag
12840.0
Vehículo utilitario, con airbag, con xenon
13140.0
‣ Como se indicó anteriormente, una uso habitual de este patrón es el uso de la jerarquía de las clases IO de Java.
‣ En este ejemplo podemos ver como la clase básica se “envuelve” en sucesivas clases mejoradas, que ofrecen mas
funcionalidad que la clase original
InputStream ins = System.in;
InputStreamReader isr = new InputStreamReader(ins);
BufferedReader br = new BufferedReader(isr);
String linea = br.readLine();
System.in hace referencia a la entrada
estándar, normalmente teclado
El objeto ins (de InputStream) se pasa al constructor de
InputStreamReader que devuelve un objeto isr “mejorado”,
ya puede leer chars por el canal
El objeto isr (de InputStreamReader) se pasa al constructor de
BufferedReader que devuelve un objeto br “aun más mejorado”,
que ya puede leer lineas completas por el canal
Patron Decorador (Decorator) (IV)
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Objetos anónimos
Objetos anónimos
22
๏ Esta utilidad ya se ha visto muchas veces probablemente, pero la revisamos ahora para aclarar su
naturaleza
๏ Los objetos en Java se crean con la instrucción new. Realmente, se llama al constructor de la clase y con
la instrucción new se construye el objeto, y posteriormente, el objeto creado se asigna a una
"variable" que almacene el objeto. Se llama objeto a la variable, pero ésta realmente lo que hace es
guardar la referencia a donde se almacena la variable.
๏ Realmente, pues, con ejecutar simplemente ya se crea un objeto. Lo que pasa es que la
referencia que devuelve, se pierde.
๏ Esto es crear un objeto anónimo, sin darle nombre.
๏ Veamos su utilidad con algunos usos prácticos
Autor a1 = new Autor();
Crea el objeto ejecutando el
constructor, lo almacena en
memoria Heap, y devuelve la
referencia a su posición
Se crea la "variable" a1 (de tipo
Autor), se almacena en el Stack,
y guarda la referencia resultado
del otro lado del =
new Autor();
ArrayList<Autor> lisautores = new ArrayList<>();
lisautores.add(new Autor());
Autor nuevonombre = lisautores.get(0);
String as = new Scanner(System.in).nextLine();
new UnaVentanaSwing().lanzar();
Creamos objetos y los metemos en una colección. Una vez en la
colección, no necesitamos que tengan un nombre, por que al
recuperarlos no recuperamos el nombre, como mucho lo asignamos a
otro nuevo
También son muy útiles si se desea llamar a un método de una
clase, pero no usar la clase para nada más que eso
No es anormal crear un ventana, y usar un método para
hacerla visible. La ventana interactuará con el usuario,
sin necesitar que tenga una variable propia asociada.
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado
Clases internas o anidadas (nested classes)
23
๏ En java una clase puede tener, entre sus miembros, la declaración de otra clase. A esta clase que se escribe
dentro de otra se llama clase anidada o interna, y a la otra, clase contenedora o externa
๏ Desde dentro de la clase interna se puede acceder a todos los miembros de la clase contenedora
๏ Una clase interna puede ser private o protected (las clases normales, no)
๏ Hay varios tipos de clases internas: internas simples (miembro), locales, estáticas y anónimas
Clases Internas
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 24
๏ Para crear un objeto de la clase interna fuera de su
clase contenedora, hay que usar
todo ello siempre que:
a) la clase interna no se ha declarado privada
b) no se intente crear desde un método static (eso
obligaría a que la clase interna fuera estática)
ClaseContenedora extObj = new ClaseContenedora();
ClaseContenedora.Interna intObj = extObj.new Interna();
public class InicioDeClaseContenedora {
public void hacerCosas() {
ClaseContenedora extObj = new ClaseContenedora();
ClaseContenedora.Interna intObj = extObj.new Interna();
}
public static void main(String args[]) {
ClaseContenedora cc = new ClaseContenedora();
new InicioDeClaseContenedora().hacerCosas();
}
}
class ClaseContenedora {
String IdCC;
Interna intEnExt;
public ClaseContenedora(String IdCC) {
intEnExt = new Interna("Int1");
}
public ClaseContenedora() { }
public class Interna {
String nom;
public Interna() { }
}
}
Clases internas miembro
Clases internas miembro
๏ Es el caso más sencillo. La clase es como un miembro más de la clase contenedora (pero no static)
๏ Como son miembros de la clase contenedora, sólo existe un objeto de la clase interna cuando exista un objeto de
la clase contenedora.
๏ Los nombres de los miembros de la clase contenedora tienen que ser diferentes de los de la clase interna
๏ Una clase interna miembro no puede contener ningún miembro estático
๏ No es posible crear un objeto de la clase interna sin tener un objeto de la clase contenedora.
๏ Dentro de la clase interna se desea hacer una referencia al objeto actual de la clase contenedora se hace
mediante NombreClaseContenedora.this.
Como crear objetos de la clase interna miembro
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 25
๏ Para crear un objeto de la clase interna fuera de su
clase contenedora, hay que usar el constructor
tradicional, pero solo dentro del propio método:
InternaLocal intlocal = new InternaLocal();
class Contenedora {
int a = 44;
public void metodoConClase() {
int x = 11;
final int n = 3;
class InternaLocal {
public void mostrar() {
System.out.println("x vale " + x);
System.out.println("a vale " + a);
System.out.println("n vale " + n);
}
}
InternaLocal intlocal = new InternaLocal();
intlocal.mostrar();
}
public static void main(String args[]) {
Contenedora objContenedora = new Contenedora();
objContenedora.metodoConClase();
}
}
Clases internas locales
Clases internas locales
๏ La clase no es un miembro directo de la clase contenedora, sino que se crea dentro de un método de la clase
contenedora. Por lo tanto, como cualquier variable local a un método, supone estas características:
‣ su visibilidad se restringe al interior del propio método
‣ la clase interna no puede ser private ni public ni protected
‣ no es posible crear un objeto de la clase interna fuera del propio método donde se declara la clase interna (pues
como ya se dijo, su visibilidad se restringe al interior del propio método)
๏ Desde la clase interna se puede acceder a todos los miembros de la clase envolvente, y a los parámetros final del
método envolvente.
๏ Puede definir sus propios atributos, pero no pueden ser estáticos.
Como crear objetos de la clase interna local
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Clases internas static 26
Clases internas static
๏ Una clase interna static que es miembro de la contenedora, pero miembro static, con lo que se comporta como
cualquier otro static:
- Se puede acceder a la clase interna sin instanciar la clase contenedora (como cualquier otro static)
- No tiene acceso a los miembros de la clase contenedora, salvo que estos también sean static
๏ Una clase interna static puede declarar su propios miembros, estáticos o no.
class Contenedora {
static class InternaEstatica {
public void pintar() {
System.out.println(“En la clase interna estática");
}
}
public static void main(String args[]) {
Contenedora.InternaEstatica intstatic =
new Contenedora.InternaEstatica();
intstatic.pintar();
}
}
Como crear objetos de la clase interna static
๏ Para crear un objeto de la clase interna static fuera
de su clase contenedora, basta con usar :
Contenedora.InternaEstatica intstatic =
new Contenedora.InternaEstatica();
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Clases anónimas (I) 27
Clases anónimas
๏ Una clase anónima es una clase interna que se crea sin nombre, y que crea un único objeto de la clase
๏ Es útil para crear una clase sin tener que heredar expresamente de otra, cuando solo necesitamos un objeto
๏ Se utiliza mucho por ejemplo con listeners en interfaces gráficas o con interfaces funcionales
๏ Se pueden crear de dos formas:
class MiClaseConHilo {
public static void main(String[] args) {
Thread hilo = new Thread() {
public void run() {
System.out.println("hola!");
}
};
hilo.start();
}
}
1 Clase anónima que extiende de otra clase o
de otra interfaz.
abstract class Comida{
abstract public void mostrar() ;
}
class PruebaInternas {
public static void main(String[] args) {
Comida com = new Comida() {
public void mostrar() {
System.out.println("Sosa !");
}
};
System.out.println(com instanceof Comida);
com.mostrar();
}
}
2 Clase anónima como parámetro de un método
interface IPerro {
String ladra();
}
class PruebaPerro {
public void haciendoruido(IPerro p) {
System.out.println(p.ladra());
}
public static void main(String args[]) {
PruebaPerro pp = new PruebaPerro();
pp.haciendoruido( new IPerro() {
public String ladra() {
return "GUAU !";
}
});
}
}
boton1.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
System.out.println("Pulso el boton 1");
}
});
Si un método recibe un objeto de una clase o interfaz
como argumento, podemos pasar dicho objeto en el
argumento, o también podemos pasar como argumento una
clase anónima, con la descripción de su contenido
Consiste en definir la clase justo tras la llamada al constructor,
entre llaves, en vez de hacerlo en un fichero separado
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado 28
๏ Una clase anónima puede acceder sin problema a los miembros de la clase contenedora
๏ Una clase anónima accede a las variables locales de la clase contenedora si estos son declarados final
๏ Una clase anónima no puede tener inicializadores static.
๏ La clase contenedora, como en el resto de casos de clases internas, no tiene acceso directo a los miembros y
variables de la clase anónima.
Características de las clases anónimas
๏ Una clase normal puede implementar muchas interfaces, pero una anónima solo una
๏ Una clase normal puede implementar y extender a la vez, pero una anónima solo una de ambas cosas, no las dos
๏ Una clase anónima no puede tener constructor (no tiene nombre, raro sería el constructor …)
Como acceder desde una anónima a miembros de contenedora y viceversa
Clases anónimas (II)
TemariodecursoJavaSE©IñakiMartín
7.- Clases y objetos 29Clases Internas: static, miembro, locales, anónimas
/ CLASE EXTERNA
class Formula1{
String escuderia;
static double presupuesto ;
double deudas; ;
// CLASE INTERNA MIEMBRO (NO ESTATICA)
class Piloto{
String nombrePiloto;
int edadPiloto;
public void pintarDatos(){
System.out.println(escuderia+": "+(presupuesto-deudas));
}
}
// CLASE INTERNA ESTATICA
static class Motor{
int potencia;
static int numCilindros;
public double redimiento(){
return presupuesto/potencia;
}
}
public void metodoConClase(){
// CLASE LOCAL
class ClaseDelMetodo{
int id;
}
ClaseDelMetodo s = new ClaseDelMetodo();
}
public void informacion(){
System.out.println(escuderia+": Piloto: "+ Motor.numCilindros);
System.out.println(nombrePiloto);
Piloto p = new Piloto();
p.edadPiloto=23;
Motor m = new Motor();
m.potencia=423;
ClaseDelMetodo s = new ClaseDelMetodo();
}
}
class MiClaseConHilo {
public static void main(String[] args) {
Thread hilo = new Thread() {
public void run() {
System.out.println("hola!");
}
};
hilo.start();
}
}
CLASE INTERNA ESTÁTICA
Solo puede acceder a los miembros estáticos de la clase contenedora.
Puede definir sus propios atributos, estáticos o no.
CLASE INTERNA MIEMBRO (NO ESTÁTICA)
Puede acceder a todos los miembros de la clase contenedora.
Puede definir sus propios atributos, pero no pueden ser
estáticos.
CLASE LOCAL
(DENTRO DE UN METODO)
Puede acceder a todos los miembros de la clase contenedora, y a
los parámetros final del método contenedor.
Puede definir sus propios atributos, pero no pueden ser estáticos.
VISIBILIDAD DE LOS MIEMBROS DE LAS CLASES INTERNAS
No se puede acceder a los miembros de una clase interna desde su
clase contenedora, salvo que;
- sean estáticos y se acceda de modo estático con el nombre de la
clase.
- Se creen instancias de las clases internas en la clase contenedora,
salvo en el caso de la clase local, de la que solo pueden crearse
instancias dentro del mismo método donde se declara
CLASE ANÓNIMA
Puede acceder a todos los miembros de la clase contenedora, y a
los parámetros final del método envolvente.
Puede definir sus propios atributos, pero no pueden ser estáticos.
No puede tener constructor
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Metodos default e interfaz funcional
Métodos default
30
๏ Java 8 incluye como novedad la posibilidad de que las interfaces tengan código, algo que hasta
entonces estaba vetado
๏ Ahora, en una interfaz se pueden añadir métodos default, que tienen estas características:
- Tienen que tener su implementación escrita, como cualquier método normal no abstracto
- A la hora de implementar la interfaz, podemos hacer varias cosas con el/los métodos default:
‣ No hacer nada, con lo que se "heredan" tal y como están.
‣ Reescribirlos y cambiar su comportamiento.
‣ Redeclararlos como método abstracto, que necesitaría implementación de las siguientes subclases.
๏ Estos métodos son útiles cuando haya un desarrollo ya creado, con muchas clases implementando una
interfaz, que nos interese hacer crecer. Con un método default pueden convivir las antiguas clases con las
futuras a crear
๏ Es solo un concepto, no un nuevo elemento. Aparece como concepto en la version Java 8
๏ Son interfaces que tienen solamente un método abstracto, es decir puede implementar uno o más
métodos default, pero deberá tener forzosamente un único método abstracto.
๏ Se escriben como una interfaz normal, no necesitan definirse de modo alguno. Es solo un concepto.
๏ Son especialmente útiles con expresiones Lambda
๏ Para asegurarnos de que estamos definiendo correctamente una interface funcional, podemos añadir la
anotación @FunctionalInterface 
Interfaces funcionales
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Expresiones Lambda (Java 8) 31
๏ Las expresiones lambda son métodos anónimos, es decir, métodos que no necesitan una clase.
๏ Se deben usar con Interfaces Funcionales
En realidad se pueden usar con cualquier CLASE ABSTRACTA (o INTERFAZ) que tengan SOLO un método abstracto
๏ La expresión lambda contiene la implementación del método abstracto de la Interfaz Funcional.
๏ Valen por ejemplo para resumir codigo en llamadas a clases internas (amen de otras cosas)
๏ Su formato normal es ( parámetros ) -> {  cuerpo }
i. El operador lambda (->) separa la declaración de parámetros de la declaración del cuerpo de la función.
ii. Parámetros:
‣ Cuando se tiene un solo parámetro no es necesario utilizar los paréntesis.
‣ Cuando no se tienen parámetros, o cuando se tienen dos o más, es necesario utilizar paréntesis.
iii. Cuerpo de lambda:
‣ Cuando el cuerpo de la expresión lambda tiene una única línea no es necesario utilizar las llaves y no
necesitan especificar la cláusula return en el caso de que deban devolver valores.
‣ Cuando el cuerpo de la expresión lambda tiene más de una línea se hace necesario utilizar las llaves
y es necesario incluir la cláusula return en el caso de que la función deba devolver un valor .
Lamba Expresions
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Expresiones Lambda (Java 8) 32
๏ Cuando se crea una expresión lambda, ésta se convierte en un "objeto", que se puede asignar a un valor de una
Interfaz Funcional
interface IPruebaLambda { // un solo metodo abstracto
int sumaIntYString(int num1, String num2);
}
// Formato lambda en modo instrucción. Puede hacerse más resumido
IPruebaLambda objIPL = (numero, cadena) -> {
return numero + Integer.parseInt(cadena);
};
// Formato lambda en modo expresion
IPruebaLambda objIPLDos = (int numero, String cadena) -> numero + Integer.parseInt(cadena);
// No es necesario el tipo de dato en los parámetros, el compilador lo infiere automaticamente.
IPruebaLambda objIPLTres = ( numero, cadena) -> numero + Integer.parseInt(cadena);
System.out.println(objIPL.sumaIntYString(3,"345"));
System.out.println(objIPLDos.sumaIntYString(3,"345"));
System.out.println(objIPLTres.sumaIntYString(3,"345"));
// Usamos aun la misma interfaz IPruebaLambda
IPruebaLambda objIPLDuplicado = ( numero, cadena) -> (numero*2) + (Integer.parseInt(cadena)*2);
System.out.println(objIPLDuplicado.sumaIntYString(3,"345"));
๏ Importante: el desarrollo del método anónimo puede ser diferente para cada objeto de la interfaz que se quiera crear
consola
348
348
348
consola
696
Interfaz Funcional: de ella solo tenemos claro que hay un método que tiene dos parámetros. Lo que
haga el método se puede escribir en una expresión lambda, tantas veces y tan distintas como se quiera
Ejemplo de desarrollo de la interfaz con expresiones lambda
Ejemplo de desarrollo diferente de la interfaz con expresiones lambda
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Expresiones Lambda (Java 8) 33
๏ Ejemplo de uso de expresiones Lambda con Hilos.
๏ Los hilos lanzados por la clase Thread son objetos de herederos de la interfaz Runnable, que solo tiene un método
abstracto, el run() de los hilos. Esta interfaz puede actuar de interfaz funcional, asi que se puede implementar el método run
como método anónimo con una expresión lambda:
// EJEMPLO 1
class EjemploHiloConLambda {
public static void main(String[] args) throws InterruptedException {
Runnable objDeMetodoRun = () -> {
System.out.println("Estoy dentro del Run de un hilo");
};
Thread MiHilo = new Thread(objDeMetodoRun);
MiHilo.start();
}
}
// EJEMPLO 2
class EjemploHiloConLambda2 {
public static void main(String[] args) throws InterruptedException {
Thread MiHilo = new Thread(MétodoQueDevuelveUnRunnable());
MiHilo.start();
}
static Runnable MétodoQueDevuelveUnRunnable() {
Runnable objDeMetodoRun = () -> {
System.out.println("Estoy dentro del Run de un hilo");
};
return objDeMetodoRun;
}
}
// EJEMPLO 3
class EjemploHiloConLambda3 {
public static void main(String[] args) throws InterruptedException {
Thread MiHilo = new Thread(MétodoQueDevuelveUnRunnable());
MiHilo.start();
}
private static Runnable MétodoQueDevuelveUnRunnable() {
return () -> {
System.out.println("Estoy dentro del Run de un hilo");
};
}
}
consola
Estoy dentro del run de un hilo
Crear el método run como anónimo, y
asignarlo a un objeto de la interfaz Runnable
Crear el hilo con el objeto de Runnable, que es lo
que necesita Thread en el constructor
Ahora Thread lo que recibe en el constructor es lo que
devuelve un método nuevo (que devuelve un Runnable)
Este es el método nuevo, que crea el mismo objeto
Runnable del ejemplo 1, y lo devuelve con un return normal
Por pura sustitución, ponemos dentro del método un return,
que devuelve lo que valia antes objDeMetodoRun
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Expresiones Lambda (Java 8) 34
// Implementacion de escuchador SIN clase anonima
class ProbarListenerSinAnonima {
public static void main(String args[]) {
JButton button = new JButton("Pusar aqui");
// Aqui se añade el eescuchador al boton como un nuevo objeto de mi clase escuchadora
miClaseActionListener mial = new miClaseActionListener();
button.addActionListener(mial));
}
}
class miClaseActionListener implements ActionListener {
public void actionPerformed(ActionEvent evt) {
System.out.println("ha pulsado el boton!");
}
}
// Implementacion de escuchador CON clase anonima
class ProbarLambdaListener {
public static void main(String args[]) {
JButton button = new JButton("Pusar aqui");
// Aqui se añade la clase anonima como si fuera el objeto de mi escuchador
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("ha pulsado el boton!");
}
});
}
}
// Implementacion de escuchador CON METODO LAMBDA
class ProbarLambdaListener {
public static void main(String args[]) {
JButton button = new JButton("Pusar aqui");
// Como ActionListener es una interface que tiene solo un metodo, actionPerformed(),
// es una interface funcional, asi que es idonea para usar una expresion Lambda
button.addActionListener(e -> System.out.println("ha pulsado el boton!"));
}
}
๏ Ejemplo de uso de expresiones Lambda con Listeners de Swing (o Android).
Sin Lambda,
y sin clase
anónima
Sin Lambda,
y con clase
anónima
Con Lambda
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Uso de var en Java 10 35
public class PruebasVar {
public static void main(String[] args) {
var list = new ArrayList<>(); // INFIERE QUE list ES UN ARRAYLIST
int x = 12;
if (x % 2 == 0) {
var z = 2; // INFIERE QUE list ES UN INT
var cla = new ClavoSinPunta(); //cla es un CLAVOSINPUNTA, no un CLAVO
}
}
}
class Clavo {
}
class ClavoSinPunta extends Clavo {
}
๏ Desde la version 10 de Java se puede usar var para declarar variables locales, y el compilador infiere, según el
contenido que tenga, que tipo de dato va a tener la variable: Ejemplos de uso:
Usos permitidos
Uso de var en java
public class PruebasVar{
var z = 2; // NO SE PUEDE USAR VAR EN ATRIBUTO DE CLASE
public static void main(String[] args) {
var algo = null; // NO SE PUEDE INICIALIZAR UN VAR A NULL
var z = () -> {}; // NO SE PUEDE USAR VAR CON EXPRESIONES LAMBDA
}
public void sumar(var x) { // NO SE PUEDE USAR VAR EN PARAMETRO DE METODO
}
}
Usos prohibidos
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Creación de JAR 36
๏ Una aplicación java se puede empaquetar en un fichero único, que puede ser ejecutado directamente desde el
sistema operativo, sin usar un IDE como Eclipse o Netbeans. Explicamos como hacerlo con varios IDE:
Uso de var en java
(Click derecho sobre el
proyecto) File -> Export
-> Java -> JAR File
Seleccionar el
proyecto a
comprimir y el
nombre y
directorio donde
crearlo. Es
importante que
haya permisos
en el directorio.
Seguir con
Next, no con
Finish
crear JAR desde ECLIPSE
Seguir con Next, no
con Finish, hasta llegar
a esta pantalla, “JAR
Manifest Specification”.
En ella es importante
que esté marcada la
opción Generate the
manifest File, y que esté
seleccionada la clase
que contiene el
método main de inicio
de proyecto
Acabar con Finish.
1
2
3
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Creación de JAR 37
File -> Project Structure
Artifacts -> (+) -> JAR -> From modules…
Seleccionar proyecto (viene por defecto) y clase que contiene el main (no olvidar).
Resto de opciones no tocarlas
Con lo anterior se crea un
artefacto, que es como un
generador de elementos. Ahora
vamos a generar el jar de
verdad.
BUild-< Build artifacts Seleccionamos el
artefacto :jar que
haya, y la opción Build
Con lo anterior se crea un directorio
classes, a la misma altura que el src
del proyecto, que tiene dentro el
fichero .jar con el proyecto
Se puede invocar a este .jar
directamente fuera del IDE y ver
como se ejecuta directamente (si es
una aplicación UI, con ventanas) o
se puede ejecutar desde una
terminal, con la orden
$ java -jar nombredeljar.jar
crear JAR desde INTELLIj
1
2
3
4
5
6
TemariodecursoJavaSE©IñakiMartín

21.- JSE Avanzado Creación de JAR 38
(Con el proyecto seleccionado en el Package Explorer)
FIle - > Project Properties
En opción Packaging, marcamos “Build Jar after Compiling” . SI el proyecto tiene librerías externas, marcar también
“Copy Dependent Libraries”
crear JAR desde NETBEANS
1
2
3 Finalizar con OK.
Luego se hace ejecutar el proyecto o se
solicita “Build” o “Clean and build”
El fichero jar se deja por defecto en la
carpeta “dist” del proyecto, aunque se
puede modificar en las propiedades, en
esta caja

Más contenido relacionado

La actualidad más candente

Pruebas de aceptación 15 11_2013
Pruebas de aceptación 15 11_2013Pruebas de aceptación 15 11_2013
Pruebas de aceptación 15 11_2013dayaorte
 
Metodologia para resolver problemas con Programacion orientada a Objetos
Metodologia para resolver problemas con Programacion orientada a ObjetosMetodologia para resolver problemas con Programacion orientada a Objetos
Metodologia para resolver problemas con Programacion orientada a ObjetosWilliam Diaz S
 
Gestión de errores en Java
Gestión de errores en JavaGestión de errores en Java
Gestión de errores en Javaeccutpl
 
Programación java1
Programación java1Programación java1
Programación java1jbersosa
 
Uso de Excepciones en JAVA
Uso de Excepciones en JAVAUso de Excepciones en JAVA
Uso de Excepciones en JAVAinnovalabcun
 
Junit con netbeans
Junit con netbeansJunit con netbeans
Junit con netbeansbachispasaca
 
TEMA Nº 8: CONTROL DE EJECUCIÓN Y MANTENIMIENTO DE SESIÓN
TEMA Nº 8: CONTROL DE EJECUCIÓN Y MANTENIMIENTO DE SESIÓNTEMA Nº 8: CONTROL DE EJECUCIÓN Y MANTENIMIENTO DE SESIÓN
TEMA Nº 8: CONTROL DE EJECUCIÓN Y MANTENIMIENTO DE SESIÓNAnyeni Garay
 
Manejo de excepciones en Java
Manejo de excepciones en JavaManejo de excepciones en Java
Manejo de excepciones en JavaJohn Ortiz
 
Tutorial JPA Parte 1 : CRUD BASICO CON JPA Y SWING en NETBEANS
Tutorial  JPA Parte 1  : CRUD BASICO CON JPA Y SWING en NETBEANSTutorial  JPA Parte 1  : CRUD BASICO CON JPA Y SWING en NETBEANS
Tutorial JPA Parte 1 : CRUD BASICO CON JPA Y SWING en NETBEANSWilliam Diaz S
 
Programación III (Java) - 04 Excepciones
Programación III (Java) - 04 ExcepcionesProgramación III (Java) - 04 Excepciones
Programación III (Java) - 04 ExcepcionesAndoni Eguíluz Morán
 
Mas sobre excepciones
Mas sobre excepcionesMas sobre excepciones
Mas sobre excepcionesjbersosa
 
Las excepciones standar
Las excepciones standarLas excepciones standar
Las excepciones standarjbersosa
 

La actualidad más candente (20)

Introducción a java
Introducción a javaIntroducción a java
Introducción a java
 
Pruebas de aceptación 15 11_2013
Pruebas de aceptación 15 11_2013Pruebas de aceptación 15 11_2013
Pruebas de aceptación 15 11_2013
 
Metodologia para resolver problemas con Programacion orientada a Objetos
Metodologia para resolver problemas con Programacion orientada a ObjetosMetodologia para resolver problemas con Programacion orientada a Objetos
Metodologia para resolver problemas con Programacion orientada a Objetos
 
Gestión de errores en Java
Gestión de errores en JavaGestión de errores en Java
Gestión de errores en Java
 
Semana 2 Clases y Objetos en Java
Semana 2   Clases y Objetos en JavaSemana 2   Clases y Objetos en Java
Semana 2 Clases y Objetos en Java
 
Semana 5 Java Swing
Semana 5   Java SwingSemana 5   Java Swing
Semana 5 Java Swing
 
Programación java1
Programación java1Programación java1
Programación java1
 
Uso de Excepciones en JAVA
Uso de Excepciones en JAVAUso de Excepciones en JAVA
Uso de Excepciones en JAVA
 
Junit con netbeans
Junit con netbeansJunit con netbeans
Junit con netbeans
 
Qunit CookBook español
Qunit CookBook españolQunit CookBook español
Qunit CookBook español
 
Semana 3 Herencia en Java
Semana 3   Herencia en JavaSemana 3   Herencia en Java
Semana 3 Herencia en Java
 
TEMA Nº 8: CONTROL DE EJECUCIÓN Y MANTENIMIENTO DE SESIÓN
TEMA Nº 8: CONTROL DE EJECUCIÓN Y MANTENIMIENTO DE SESIÓNTEMA Nº 8: CONTROL DE EJECUCIÓN Y MANTENIMIENTO DE SESIÓN
TEMA Nº 8: CONTROL DE EJECUCIÓN Y MANTENIMIENTO DE SESIÓN
 
Manejo de excepciones en Java
Manejo de excepciones en JavaManejo de excepciones en Java
Manejo de excepciones en Java
 
Tutorial JPA Parte 1 : CRUD BASICO CON JPA Y SWING en NETBEANS
Tutorial  JPA Parte 1  : CRUD BASICO CON JPA Y SWING en NETBEANSTutorial  JPA Parte 1  : CRUD BASICO CON JPA Y SWING en NETBEANS
Tutorial JPA Parte 1 : CRUD BASICO CON JPA Y SWING en NETBEANS
 
Best Practices
Best PracticesBest Practices
Best Practices
 
Programación III (Java) - 04 Excepciones
Programación III (Java) - 04 ExcepcionesProgramación III (Java) - 04 Excepciones
Programación III (Java) - 04 Excepciones
 
Mas sobre excepciones
Mas sobre excepcionesMas sobre excepciones
Mas sobre excepciones
 
Datos Previos
Datos PreviosDatos Previos
Datos Previos
 
Datos Previos
Datos PreviosDatos Previos
Datos Previos
 
Las excepciones standar
Las excepciones standarLas excepciones standar
Las excepciones standar
 

Similar a Jyoc java-cap21 jse avanzado

Java fundamentos -15 consejos prácticos - Encuentro Universitario Comunidad J...
Java fundamentos -15 consejos prácticos - Encuentro Universitario Comunidad J...Java fundamentos -15 consejos prácticos - Encuentro Universitario Comunidad J...
Java fundamentos -15 consejos prácticos - Encuentro Universitario Comunidad J...Eudris Cabrera
 
Fundamentos de Java / 15 consejos prácticos sobre Java que cambiarán la for...
Fundamentos de Java /   15 consejos prácticos sobre Java que cambiarán la for...Fundamentos de Java /   15 consejos prácticos sobre Java que cambiarán la for...
Fundamentos de Java / 15 consejos prácticos sobre Java que cambiarán la for...Eudris Cabrera
 
Java fundamentos -15 consejos practicos open saturday 2018
Java fundamentos -15 consejos practicos open saturday 2018Java fundamentos -15 consejos practicos open saturday 2018
Java fundamentos -15 consejos practicos open saturday 2018Eudris Cabrera
 
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)Oscar V
 
Java fundamentos 15 consejos prácticos - ITLA Tech Day 2018
Java fundamentos   15 consejos prácticos - ITLA Tech Day 2018Java fundamentos   15 consejos prácticos - ITLA Tech Day 2018
Java fundamentos 15 consejos prácticos - ITLA Tech Day 2018Eudris Cabrera
 
Compilador (divisor de cantidades )
Compilador (divisor de cantidades )Compilador (divisor de cantidades )
Compilador (divisor de cantidades )Soraya Lara
 
Informe compilador divisor
Informe compilador divisorInforme compilador divisor
Informe compilador divisorSoraya Lara
 
Compilador divisor de cantidades con Jflex y Cup
Compilador divisor de cantidades con Jflex y CupCompilador divisor de cantidades con Jflex y Cup
Compilador divisor de cantidades con Jflex y CupSoraya Lara
 
Información básica Java
Información básica JavaInformación básica Java
Información básica JavaFordBull2er
 
Unidad 2 programación estructurada
Unidad 2 programación estructuradaUnidad 2 programación estructurada
Unidad 2 programación estructuradaRoberth Camana
 
Caracteristicas de C Sharp
Caracteristicas de C SharpCaracteristicas de C Sharp
Caracteristicas de C SharpEdgardo Martinez
 
Estructuras De Control
Estructuras De ControlEstructuras De Control
Estructuras De ControlUPS
 

Similar a Jyoc java-cap21 jse avanzado (20)

Java fundamentos -15 consejos prácticos - Encuentro Universitario Comunidad J...
Java fundamentos -15 consejos prácticos - Encuentro Universitario Comunidad J...Java fundamentos -15 consejos prácticos - Encuentro Universitario Comunidad J...
Java fundamentos -15 consejos prácticos - Encuentro Universitario Comunidad J...
 
Fundamentos de Java / 15 consejos prácticos sobre Java que cambiarán la for...
Fundamentos de Java /   15 consejos prácticos sobre Java que cambiarán la for...Fundamentos de Java /   15 consejos prácticos sobre Java que cambiarán la for...
Fundamentos de Java / 15 consejos prácticos sobre Java que cambiarán la for...
 
Java fundamentos -15 consejos practicos open saturday 2018
Java fundamentos -15 consejos practicos open saturday 2018Java fundamentos -15 consejos practicos open saturday 2018
Java fundamentos -15 consejos practicos open saturday 2018
 
Grupo1
Grupo1Grupo1
Grupo1
 
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)
OCP, JSE 6 Programmer (1z0-851) - Guia practica 3 de 7(ap-is)
 
Java fundamentos 15 consejos prácticos - ITLA Tech Day 2018
Java fundamentos   15 consejos prácticos - ITLA Tech Day 2018Java fundamentos   15 consejos prácticos - ITLA Tech Day 2018
Java fundamentos 15 consejos prácticos - ITLA Tech Day 2018
 
preparedstatement
preparedstatementpreparedstatement
preparedstatement
 
Compilador (divisor de cantidades )
Compilador (divisor de cantidades )Compilador (divisor de cantidades )
Compilador (divisor de cantidades )
 
Informe compilador divisor
Informe compilador divisorInforme compilador divisor
Informe compilador divisor
 
Compilador divisor de cantidades con Jflex y Cup
Compilador divisor de cantidades con Jflex y CupCompilador divisor de cantidades con Jflex y Cup
Compilador divisor de cantidades con Jflex y Cup
 
Información básica Java
Información básica JavaInformación básica Java
Información básica Java
 
Documento Margarita
Documento MargaritaDocumento Margarita
Documento Margarita
 
Unidad 2 programación estructurada
Unidad 2 programación estructuradaUnidad 2 programación estructurada
Unidad 2 programación estructurada
 
Lenguaje de Alto Nivel
Lenguaje de Alto NivelLenguaje de Alto Nivel
Lenguaje de Alto Nivel
 
Manejo de memoria
Manejo de memoriaManejo de memoria
Manejo de memoria
 
Documeto compilardorcontadorletras
Documeto compilardorcontadorletrasDocumeto compilardorcontadorletras
Documeto compilardorcontadorletras
 
Comandos Java
Comandos JavaComandos Java
Comandos Java
 
Caracteristicas de C Sharp
Caracteristicas de C SharpCaracteristicas de C Sharp
Caracteristicas de C Sharp
 
Comandos de Java
Comandos de JavaComandos de Java
Comandos de Java
 
Estructuras De Control
Estructuras De ControlEstructuras De Control
Estructuras De Control
 

Más de Jyoc X

Jyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc X
 
Jyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc X
 
Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc X
 
Jyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc X
 
Jyoc java-cap17 persistencia. nio
Jyoc java-cap17 persistencia. nioJyoc java-cap17 persistencia. nio
Jyoc java-cap17 persistencia. nioJyoc X
 
Jyoc java-cap15 persistencia. ficheros xml, j son y pdf
Jyoc java-cap15 persistencia. ficheros xml, j son y pdfJyoc java-cap15 persistencia. ficheros xml, j son y pdf
Jyoc java-cap15 persistencia. ficheros xml, j son y pdfJyoc X
 
Jyoc java-cap14 persistencia. ficheros corrientes
Jyoc java-cap14 persistencia. ficheros corrientesJyoc java-cap14 persistencia. ficheros corrientes
Jyoc java-cap14 persistencia. ficheros corrientesJyoc X
 
Jyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc X
 
Jyoc java-cap11 colecciones
Jyoc java-cap11 coleccionesJyoc java-cap11 colecciones
Jyoc java-cap11 coleccionesJyoc X
 
Jyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc X
 
Jyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc X
 
Jyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc X
 
Jyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc X
 
Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc X
 
Jyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc X
 
Jyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc X
 

Más de Jyoc X (16)

Jyoc java-cap22 seguridad
Jyoc java-cap22 seguridadJyoc java-cap22 seguridad
Jyoc java-cap22 seguridad
 
Jyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilasJyoc java-cap20 listas, colas y pilas
Jyoc java-cap20 listas, colas y pilas
 
Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)Jyoc java-cap19 tad (tipos abstractos de datos)
Jyoc java-cap19 tad (tipos abstractos de datos)
 
Jyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fxJyoc java-cap18 swing y java fx
Jyoc java-cap18 swing y java fx
 
Jyoc java-cap17 persistencia. nio
Jyoc java-cap17 persistencia. nioJyoc java-cap17 persistencia. nio
Jyoc java-cap17 persistencia. nio
 
Jyoc java-cap15 persistencia. ficheros xml, j son y pdf
Jyoc java-cap15 persistencia. ficheros xml, j son y pdfJyoc java-cap15 persistencia. ficheros xml, j son y pdf
Jyoc java-cap15 persistencia. ficheros xml, j son y pdf
 
Jyoc java-cap14 persistencia. ficheros corrientes
Jyoc java-cap14 persistencia. ficheros corrientesJyoc java-cap14 persistencia. ficheros corrientes
Jyoc java-cap14 persistencia. ficheros corrientes
 
Jyoc java-cap13 recursividad
Jyoc java-cap13 recursividadJyoc java-cap13 recursividad
Jyoc java-cap13 recursividad
 
Jyoc java-cap11 colecciones
Jyoc java-cap11 coleccionesJyoc java-cap11 colecciones
Jyoc java-cap11 colecciones
 
Jyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumeradosJyoc java-cap10 clases complementarias y enumerados
Jyoc java-cap10 clases complementarias y enumerados
 
Jyoc java-cap08 principios poo
Jyoc java-cap08 principios pooJyoc java-cap08 principios poo
Jyoc java-cap08 principios poo
 
Jyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetosJyoc java-cap07 clases y objetos
Jyoc java-cap07 clases y objetos
 
Jyoc java-cap06 la clase string
Jyoc java-cap06 la clase stringJyoc java-cap06 la clase string
Jyoc java-cap06 la clase string
 
Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)Jyoc java-cap04 vectores (arrays)
Jyoc java-cap04 vectores (arrays)
 
Jyoc java-cap03 bucles
Jyoc java-cap03 buclesJyoc java-cap03 bucles
Jyoc java-cap03 bucles
 
Jyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salidaJyoc java-cap01 tipos de datos y entrada-salida
Jyoc java-cap01 tipos de datos y entrada-salida
 

Último

Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxaylincamaho
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024GiovanniJavierHidalg
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdfIsabellaMontaomurill
 
Clase N°4 - Purificación y secuenciación de acidos nucleicos Benoit Diringer ...
Clase N°4 - Purificación y secuenciación de acidos nucleicos Benoit Diringer ...Clase N°4 - Purificación y secuenciación de acidos nucleicos Benoit Diringer ...
Clase N°4 - Purificación y secuenciación de acidos nucleicos Benoit Diringer ...Luis Olivera
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELmaryfer27m
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptMiguelAtencio10
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxJOSEFERNANDOARENASCA
 
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfSergioMendoza354770
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadMiguelAngelVillanuev48
 
ejercicios pseint para aprogramacion sof
ejercicios pseint para aprogramacion sofejercicios pseint para aprogramacion sof
ejercicios pseint para aprogramacion sofJuancarlosHuertasNio1
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfsoporteupcology
 
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...JaquelineJuarez15
 
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...FacuMeza2
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesFundación YOD YOD
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx241523733
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.241514949
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxpabonheidy28
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxazmysanros90
 
definicion segun autores de matemáticas educativa
definicion segun autores de matemáticas  educativadefinicion segun autores de matemáticas  educativa
definicion segun autores de matemáticas educativaAdrianaMartnez618894
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaarkananubis
 

Último (20)

Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
 
Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024Cortes-24-de-abril-Tungurahua-3 año 2024
Cortes-24-de-abril-Tungurahua-3 año 2024
 
trabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdftrabajotecologiaisabella-240424003133-8f126965.pdf
trabajotecologiaisabella-240424003133-8f126965.pdf
 
Clase N°4 - Purificación y secuenciación de acidos nucleicos Benoit Diringer ...
Clase N°4 - Purificación y secuenciación de acidos nucleicos Benoit Diringer ...Clase N°4 - Purificación y secuenciación de acidos nucleicos Benoit Diringer ...
Clase N°4 - Purificación y secuenciación de acidos nucleicos Benoit Diringer ...
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFEL
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.ppt
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptx
 
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidad
 
ejercicios pseint para aprogramacion sof
ejercicios pseint para aprogramacion sofejercicios pseint para aprogramacion sof
ejercicios pseint para aprogramacion sof
 
Redes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdfRedes direccionamiento y subredes ipv4 2024 .pdf
Redes direccionamiento y subredes ipv4 2024 .pdf
 
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
El gusano informático Morris (1988) - Julio Ardita (1995) - Citizenfour (2014...
 
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
ATAJOS DE WINDOWS. Los diferentes atajos para utilizar en windows y ser más e...
 
KELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento ProtégelesKELA Presentacion Costa Rica 2024 - evento Protégeles
KELA Presentacion Costa Rica 2024 - evento Protégeles
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.
 
Plan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docxPlan de aula informatica segundo periodo.docx
Plan de aula informatica segundo periodo.docx
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptx
 
definicion segun autores de matemáticas educativa
definicion segun autores de matemáticas  educativadefinicion segun autores de matemáticas  educativa
definicion segun autores de matemáticas educativa
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en mina
 

Jyoc java-cap21 jse avanzado

  • 1. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado TEMARIO DE CURSO PROGRAMACIÓN JAVA SE CAPÍTULO 21 JSE AVANZADO: • ASSERTS (AFIRMACIONES) • EXPRESIONES REGULARES • PATRONES DE DISEÑO • ANONIMOS • LAMBDA • LOGGER Este obra está bajo una licencia de Creative Commons Reconocimiento-NoComercial-SinObraDerivada 4.0 Internacional.
  • 2. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Logging ๏ Cuando un programa está en entorno de producción, es muy útil tener un log donde se guarden los errores que se producen, o mejor aun, todos los eventos que se van realizando en el programa, para poder hacer un seguimiento de como se han ido ejecutando las cosas, para explicar por ejemplo, errores que se produzcan ๏ Hay muchas librerías y frameworks para este propósito, pero Java también lo permite con la clase Java Logging Api ๏ Debemos prepara primer el entorno de logging, y luego usarlo donde deseemos. Logging 2 ➡ Preparar el entorno de log (solo hace falta hacerlo una vez en cada proyecto): ‣ Crear un objeto de tipo Logger desde el cual enviaremos los mensajes Los mensajes normalmente se envían a un fichero de texto (también se pueden enviar a la consola solamente) Si se desea usar el mismo objeto Logger desde varias clases, se recomienda que sea de tipo static ‣ Crear un objeto FileHandler y agregarlo al Logger. Este tipo de handler enviara los mensajes al archivo que le indiquemos. ‣ EL Logger escribe por defecto en formato XML (cada mensaje). Si deseamos que tenga otro formato (texto plano por ejemplo) debemos crear un objeto SimpleFormatter y asociarlo al FileHandler ➡ Guardar mensajes en el fichero de log (se realizará cada vez que se desee registrar algo en el log) ‣ Se usa el método log() del Logger, con dos parámetros : tipo de mensaje, y mensaje en si Cada entrada del log guama ademas automáticamente la fecha, hora, el nombre completo de la clase y el método y en el caso de mensajes de nivel grave la linea de código donde se genero el reporte ‣ Para los tipos de mensaje se pueden usar estas constantes - Level.INFO: Mostrar mensajes informativos - Level.CONFIG: Mostrar mensajes de configuración - Level.WARNING: Mostrar mensajes de alerta - Level.SEVERE: Mostrar mensajes críticos - Level.FINE: Mostrar mensajes de depuración de nivel 1 - Level.FINER: Mostrar mensajes de depuración de nivel 2 - Level.FINEST: Mostrar mensajes de depuración de nivel 3
  • 3. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado ๏ Ejemplo de Logger 3Logging // Se crea un objeto Logger con un nombre // Logger logger2 = Logger.getLogger("logDeMiClase"); // Sin embargo, es práctica habitual usar para el nombre del Logger // el fully qualified name de cada una de las clases (si cada clase tiene su logging, claro). Logger logger = Logger.getLogger(Miclaseactual.class.getName()); // Los handler (manejadores) indican donde mandar los mansajes, a consola o archivo // Si no se indica handler, los mensajes van solo a consola // Si no se indica un FileHandler, se envían los mensajes a un fichero (y a consola) Handler fileHandler = new FileHandler("./ficheroDeLog.log", false); // Un formateador indica como escribir los datos // Si no se usa formatter, se escriben los mensajes en formato XML // Si se desea un formato diferenrte, de debe usar un formateador, de los que existen o personalizado // Este ejemplo simple de formateador escribe el mensaje como texto plano SimpleFormatter simpleFormatter = new SimpleFormatter(); // Asi se asigna el formateador al FileHandler fileHandler.setFormatter(simpleFormatter); // Asi se asigna el FileHandler al Logge logger.addHandler(fileHandler); // Ahora ya Usamos los logger donde queramos try { logger.log(Level.INFO, "Se van a asignar valores "); int x = 43; int y = 0; if (y == 0) { logger.log(Level.WARNING, "Cuidado, puede que falle pues y es 0"); } double p = x / y; logger.log(Level.INFO, "valores ya asignados "); } catch (Exception e) { logger.log(Level.SEVERE, "ERROR, se ha producido un error"); logger.log(Level.SEVERE, e.getMessage()); } // Logger super simple, se declara y solo envía mensajes a consola public static Logger LOGGERSIMPLE = Logger.getLogger(Clases.class.getName()); LOGGERSIMPLE.log(Level.INFO, "Mensaje a la consola ");
  • 4. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Asserts ๏ Asserts son “afirmaciones”, es decir, podemos comprobar en cualquier parte de un método una expresión y ver si una afirmación (la expresión) es cierta. Si no lo es, se lanza un AssertionError, que detiene el programa. Cuidado, un AssertionError NO es una excepción, es un Error (y además, Unchecked, por lo tanto, se podría intentar capturar, pero como veremos, es justo lo que no queremos hacer) ๏ Ventajas: ๏ Forma de usar las Asserts: assert unaExpresion : stringMensaje ; ๏ donde unaExpresion es cualquier expresión que devuelve un boolean. Cuando se ejecuta el código, al llegar al assert se evalúa unaExpresion y si esta devuelve un false, Java lanza un AssertionError. El string stringMensaje es un String que se manda al constructor del AssertionError, para ayudar a que se clarifique el problema que se ha detectado. Este string es opcional (si no se usa, no se ponen tampoco los dos puntos) ๏ Los asserts se deben de utilizar para validar una variable o el valor retornado para alguna sentencia o método, no deben usarse para programar funcionalidad de la aplicación Afirmaciones (Asserts) ‣ Se usan para que el programa avise de las condiciones de la ejecución. Las Asserts no afectan a la ejecución de un código, simplemente comprueban expresiones. Son por lo tanto muy útiles en fase de pruebas y depuración de código. ‣ Las Asserts se pueden desactivar para que, aunque estén en el código, no se evaluen, con lo que no molestan ni en tiempo de poner la aplicación en producción. 4 public class PruebasAssert{ public static void main(String[] args) { int x=4; assert x==5: "X no es igual a 5"; } }
  • 5. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Properties ๏ Properties es una clase heredera de HashTable. Se usa en muchas otras clases de Java (por ejemplo, es lo que devuelve System.getProperties( ) cuando informa de los valores de las variables de entorno) ๏ Amén de otros métodos de los HashTable, tiene métodos propios para facilitar el alta y consulta de cualquier lista de “propiedades”, sea propia o generada por otras clases Properties 5 Properties valoresConexion = new Properties(); valoresConexion.put("ip", "localhost"); valoresConexion.put("puerto", "50001"); valoresConexion.put("usuario", "pepe"); valoresConexion.put("password", "12345"); String antiguoValor = (String) valoresConexion.setProperty("password", "98765"); System.out.println(antiguoValor); String laip = valoresConexion.getProperty("ip"); System.out.println(laip); String puerto = (String) valoresConexion.get("puerto"); System.out.println(puerto); for(Object clave : valoresConexion.keySet()){ System.out.println("Clave-Valor es " + clave + " - " + valoresConexion.getProperty((String)clave) + "."); } Iterator it = valoresConexion.keySet().iterator(); while(it.hasNext()) { String clave = (String) it.next(); System.out.println("la clave " + clave + " tiene valor " + valoresConexion.getProperty(clave) ); } for(){ valoresConexion.put("passwordnumerica", 42352); String antiguoValor = (String) valoresConexion.setProperty("password", "98765"); Se crea un objeto simple de la clase Properties como hereda de Map puedo añadir los elementos ea la colección con un put sin problemas También tiene un método propio setProperty(), que hace lo mismo que put, solo que ademas devuelve el valor que hubiera ante de aplicar la clave-valor nueva Para obtener una propiedad, usar el método getProperty(), o el clásico get() de los Maps. Solo recordar que el get() devuelve un Object, necesita un casting Para recorrer la colección, usar un foreach (los elementos de la colección son Objects, cuidado), o recorrer con un iterator el conjunto de las claves de la colección, y con cada clave, recoger su valor Como no se define el tipo del valor puede ser lo que se quiera, pero es peligroso usar algo que nos sea String…. De hecho, el método serProperty no deja añadir valores que no sean String
  • 6. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Una expresión regular sirve para comprobar el formato de una cadena. Se basa en definir un patrón y comprobar que la cadena cumpla las reglas de ese patron. Algunos ejemplos de patrones pueden ser: • para comprobar que la fecha leída cumple el patrón dd/mm/aaaa • para comprobar que un NIF está formado por 8 cifras, un guión y una letra • para comprobar que una dirección de correo electrónico es una dirección válida. • para comprobar que una contraseña cumple unas determinadas condiciones. • para comprobar que una URL es válida. • para comprobar cuántas veces se repite dentro de la cadena una secuencia de caracteres determinada. Para escribir el patrón (la expresión regular) se usan unos elementos con un formato específico: símbolos, metacaracteres, cuantificadores… Expresiones Regulares Expresiones regulares 6
  • 7. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Expresiones Regulares Simbolos Metacaracteres CUIDADO En Java como la expresión regular es un String, se ha de usar un doble en vez de una sola, para “escapar” la siguiente barra, esto es, no usar d, sino d Concatenación . El patron “AB” cumple si el String contiene A seguida de B . Un punto indica cualquier carácter ^ El símbolo ^ indica el principio del String. El patron “^ expresion” cumple si el String contiene expresión al principio. $ El símbolo $ indica el final del String. El patron “expresion $” cumple si el String contiene expresión al final [ ] Los corchetes representan una definición de conjunto. El patron “[abc]” cumple si el String contiene las letras a ó b ó c. El patron “[abc][12]” cumple si el String contiene las letras a ó b ó c seguidas de 1 ó 2 ^ en [ ] El símbolo ^ dentro de los corchetes indica negación. El patron “[^abc]” cumple si el String contiene cualquier carácter excepto a ó b ó c. - Rango. El patron “[a-z1-9]” cumple si el String contiene letras minúsculas desde la a hasta la z (ambas incluidas) y los dígitos desde el 1 hasta el 9 (ambos incluidos) | El carácter | es un OR. El patron “A|B” cumple si el String contiene A ó B ( ) Agrupar (como en matematicas) para aplicar modificadores o cuantificadores d Dígito. Equivale a [0-9] D No dígito. Equivale a [^0-9] s Espacio en blanco. Equivale a [ tnx0brf S No espacio en blanco. Equivale a [^s w Una letra mayúscula o minúscula, un dígito o el carácter _ Equivale a [a-zA-Z0-9_] W Equivale a [^w] b Límite de una palabra. 7
  • 8. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado CUIDADO: Si se quiere hacer referencia explicita en el patrón a un carácter que es un cuantificador, o un símbolo, ha de usarse la (en java ) para “evitar” que evalúe el carácter y lo tome simplemente como tal: el patrón (.)* indica un punto 0 o mas veces Para usar expresiones regulares en Java se usan las clases Pattern y Matcher y la excepción PatternSyntaxException (paquete java.util.regex). Para comprobaciones también se puede usar String • Clase Pattern: Contiene el método compile(String regex) que recibe como parámetro la expresión regular y devuelve un objeto de la clase Pattern, que representa la expresión regular ya “preparada”. • La clase Matcher: Esta clase compara el String y la expresión regular. Con su método matches() que recibe como parámetro el String a validar y devuelve true si coincide con el patrón. • La clase String también tiene un método matches() para evaluar directamente un patrón sobre una cadena Expresiones Regulares Cuantificadores {X} Indica que lo que va justo antes de las llaves se repite X veces {X,Y} Indica que lo que va justo antes de las llaves se repite mínimo X veces y máximo Y veces. También podemos poner {X,} indicando que se repite un mínimo de X veces sin límite máximo. * Indica 0 ó más veces. Equivale a {0,} + Indica 1 ó más veces. Equivale a {1,} ? Indica 0 ó 1 veces. Equivale a {0,1} 8 String cadena = "abc"; if (cadena.matches("^abc.*")) System.out.println("SI cumple patron"); else System.out.println("NO cumple patron"); String cadena = "abc"; Pattern pat = Pattern.compile("abc"); Matcher mat = pat.matcher(cadena); if (mat.matches()) System.out.println("SI cumple patron"); else System.out.println("NO cumple patron");
  • 9. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Expresiones Regulares EJEMPLOS de expresiones regulares Comprobar si el String cadena comienza por “abc” comienzodelinea cualquiercaracter muchasveces ^ abc . * Comprobar si el String cadena contiene exactamente “abc” Comprobar si el String cadena contiene “abc” Comprobar si el String cadena comienza por “abc” ó “Abc” cualquiercaracter muchasveces cualquiercaracter muchasveces . * abc . * Comprobar si cadena está formado por un mínimo de 5 letras mayúsculas o minúsculas y un máximo de 10 9 String cadena = "abc"; Pattern pat = Pattern.compile("abc"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "adbdc"; Pattern pat = Pattern.compile("abc"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "vavasvvccsascca"; Pattern pat = Pattern.compile("[a-zA-Z]{5,10}"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "abc"; Pattern pat = Pattern.compile(".*abc.*"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "adbc"; Pattern pat = Pattern.compile("^[aA]bc.*"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "Abc"; Pattern pat = Pattern.compile(“^[aA]bc.*”); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "aaffabc"; Pattern pat = Pattern.compile("^abc.*"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "abc"; Pattern pat = Pattern.compile("^abc.*"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "csdcWWxx"; Pattern pat = Pattern.compile("[a-zA-Z]{5,10}"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println(“NO cumple"); String cadena = "ddcabdc"; Pattern pat = Pattern.compile(".*abc.*"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple");
  • 10. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Comprobar si el String cadena es una direccion de mail valida Explicación de este último ejemplo: Expresiones Regulares Comprobar si el String cadena solo contienen los caracteres a ó b Comprobar si el String cadena contiene un 1 y ese 1 no está seguido por un 2 [w-]+ Inicio del email El signo + indica que debe aparecer uno o más de los caracteres entre corchetes: w indica caracteres de la A a la Z tanto mayúsculas como minúsculas, dígitos del 0 al 9 y el carácter _ :Carácter – En lugar de usar w podemos escribir el rango de caracteres con lo que esta expresión quedaría así: [A-Za-z0-9-_]+ (.[w-]+)* El * indica que este grupo puede aparecer cero o más veces. El email puede contener de forma opcional un punto seguido de uno o más de los caracteres entre corchetes. @ A continuación debe contener el carácter @ [A-Za-z0-9]+ Después de la @ el email debe contener uno o más de los caracteres que aparecen entre los corchetes (.[A-Za-z0-9]+)* Seguido (opcional, 0 ó más veces) de un punto y 1 ó más de los caracteres entre corchetes (.[A-Za-z]{2,}) Seguido de un punto y al menos 2 de los caracteres que aparecen entre corchetes (final del email) 10 String cadena = “aababa.bbaba@dalsd.acsa.com“; Pattern pat = Pattern.compile("^[w-]+(.[w-]+)*@[A-Za-z0-9]+(.[A-Za-z0-9]+)*(.[A-Za-z]{2,})$"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "aaffabc"; Pattern pat = Pattern.compile(".*1(?!2).*"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "aabababbaba"; Pattern pat = Pattern.compile(".*1(?!2).*"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "aaffabc"; Pattern pat = Pattern.compile("(a|b)+"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple"); String cadena = "aabababbaba"; Pattern pat = Pattern.compile("(a|b)+"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple");
  • 11. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Expresiones Regulares Comprobar si el String cadena contiene un numero de teléfono español 11 String cadena = "+34924221133"; Pattern pat = Pattern.compile("/+34 9[0-9]{1,2} [0-9]{7}/"); Matcher mat = pat.matcher(cadena); if(mat.matches()) System.out.println("SI cumple"); else System.out.println("NO cumple");
  • 12. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado • El patrón factoría consiste en construir una estructura (una clase Factoría) que ofrezca métodos para crear objetos de otra clase X. El objeto es “esconder” la clase X al público, a quien no le interesa ni cómo trabaja X ni cómo se implementa. • El patrón se ve mejor con una estructura de herencia, y mejor aun con un ejemplo. Patrones de diseño: Factoría (I) Patrón factoría 2) Creamos las clases que implementan la interfaz. En este caso son tres tipos de perros que actúan de forma diferente 12 class Caniche implements IPerro { public void ladrar() { System.out.println("El caniche dice "guau guau""); } } class Doberman implements IPerro { public void ladrar() { System.out.println(""El Doberman dice "GUAUUU GUAUUU"""); } } class Bulldog implements IPerro { public void ladrar() { System.out.println(""El Bulldog dice "No me pisoteeis mas!!""); } } interface IPerro { public void ladrar (); } 1) Creamos una interfaz, que define el contrato que han de cumplir las clases que la implementen:
  • 13. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Ventajas: • La factoría no dice que lo que devuelve es un Doberman, Caniche o Bulldog. Simplemente devuelve algo que implemente la interfaz IPerro • En el main solo le decimos a la factoría qué queremos, y la clase factoría decide qué subclase ha de crear y devolver al main. No se sabe qué clase ha creado el perro que recibimos, ni siquiera como se llama. • Por supuesto, también podemos hacer que el método getter de la factoría reciba directamente el nombre del perro. Aun y así, no se sabe qué clase o qué componente java está desarrollado para “construir” el perro solicitado, pues el nombre no es mas que una “característica” que igualmente usa la factoría para elegir lo que devuelve • El criterio de selección en este caso es sencillo, pero puede ser muy complejo, por ejemplo con más información de entrada al getter y más lógica de selección de objeto a devolver. 3) Creamos ahora la clase Factoría, la esencia del patrón. Esta factoría define un método getxx ( casi como un getter normal) que devuelve un objeto de tipo Perro, esto es, el tipo “base” de la herencia. Para “pedir” el perro, espera por argumento la información del uso se le va a dar al perro, su oficio: 4) Finalmente, vemos la factoría en acción, Los perros se crean usando la factoría, y pidiéndolos por su oficio. public class Main { public static void main(String[] args) { // crear un perro para ancianos IPerro miPerro; miPerro= PerroFactory.getPerro("ancianos"); miPerro.ladrar(); // crear un perro para defensa miPerro = PerroFactory.getPerro("defensa"); miPerro.ladrar(); // crear un perro para niños miPerro = PerroFactory.getPerro("niños"); miPerro.ladrar(); } } // Clase Factoria para Perros class PerroFactory { public static IPerro getPerro(String oficio) { if ( oficio.equals("ancianos")) return new Caniche(); else if ( oficio.equals("defensa") ) return new Doberman(); else if ( oficio.equals("niños") ) return new Bulldog(); return null; } } 13Patrones de diseño: Factoría (II)
  • 14. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado • El patrón Singleton consiste en garantizar que una clase solo tenga una instancia y proporcionar un punto de acceso global a ella. Por ejemplo, suele ser muy utilizado para las conexiones a bases de datos. • Por lo tanto, se pueden crear varios objetos de la clase, pero todos apuntan a una UNICA instancia de la misma. • Se implementa haciendo privado el constructor de la clase y creando (en la propia clase) un método que crea una instancia del objeto si este no existe, o que devuelve la instancia ya creada si ya existe • Veamos un ejemplo de este patrón. La clase ClaseConInstanciaUnica tiene un constructor privado, y un método llamado 'getUnicaInstancia()' que será el encargado de crear una instancia de esta clase si no se ha creado todavía: Patrón Singleton class ClaseConInstanciaUnica{ private String identificador; private static ClaseConInstanciaUnica unicaInstancia; // El constructor es privado, solo accesible desde el metodo getUnicaInstancia() // Asi además no se permite que se genere un constructor por defecto. private ClaseConInstanciaUnica(String identificador){ this.identificador = identificador; } // El metodo getUnicaInstancia() devuelve una instancia de esta clase. // Si no existia la instancia, la crea y devuelve, si ya existia, devuelve esa misma public static ClaseConInstanciaUnica getUnicaInstancia(String identificador){ if (unicaInstancia == null){ unicaInstancia = new ClaseConInstanciaUnica(identificador); System.out.println("Se ha creado una nueva instancia y se devuelve la referencia "); } else{ System.out.println("No se crea una nueva instancia, se devuelve la referencia " + "de la instancia ya existente"); } return unicaInstancia; } } El patrón Singleton puede dar problemas con multitarea, por lo que se deberia usar syncronized para evitarlos 14Patrones de diseño: Singleton
  • 15. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 15 ๏ El patrón de diseño Observer define una dependencia del tipo uno a muchos entre objetos, de manera que cuando un objeto s cambia su estado, notifica este cambio a otros objetos. ๏ Este patrón también se conoce como el patrón de publicación-inscripción o modelo-patrón. ๏ Se compone básicamente de: ‣ una clase (a la que se suele llamar sujeto) que es observada ‣ otros objetos de otras clases (llamadas observadores) que esperan noticias de la observada ๏ La clase Sujeto contiene atributos mediante los cuales cualquier objeto observador o vista se puede suscribir a él pasándole una referencia a sí mismo, y hace llamadas de “publicación” de cambios cuando le interesa Clase Observada Clase Observer Clase Observer Clase Observer Se envían mensajes cuando algo ocurre en la clase Observada mensaje mensaje mensaje Patrón Observer Patrones de diseño: Observer (I)
  • 16. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 16 public class Producto extends Observable { private String nombre; private int precio; private Observer observer; public Producto() { } @Override public void addObserver(Observer observer) { this.observer = observer; } public int getPrecio() { return precio; } public void setPrecio(int precio) { this.precio = precio; notifyObservers(); } public void enRebajas(int porcentaje) { this.precio = precio - (precio/100 *porcentaje); notifyObservers(); } @Override public void notifyObservers() { if (observer != null) observer.update(this, "Producto-Cambio de precio"); } } Patron Observer: el Observable ๏ El Observable es la clase que es observada, la que notifica a las demás que ha sufrido cambios La clase debe HEREDAR de Observable La clase debe tener un método addObserver(), que recibe un objeto de tipo Observer, que será cada uno de los observadores que están mirando esta clase. El observador recibido lo guarda en un atributo de tipo Observer, o si se desea muchos observadores, en una colección de Observer Cuando se produce en la clase observada alguna situación que desee compartir con los observadores, se hace en ese momento una invocación al método notifyObservers() Finalmente, se escribe el método notifyObservers(), que usa el objeto (u objetos, si es una colección) de Observers y les ejecuta el método update(). En dicho método envía una copia de la la propia clase (el this inicial) y algún contenido que identifique el cambio. El contenido es un Object, así que puede ser tanto un simple String, como cualquier objeto más complejo.
  • 17. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 17 public class Cotilla implements Observer { private String nombre; // Método que se ejecuta cuando se producen cambios @Override public void update(Observable o, Object arg) { if (arg.equals("Soy un producto y hay cambio en stock")) { System.out.println("Soy el cotilla, y ya se que el producto ha cambiado de precio!! "); Producto pp = (Producto)o; System.out.println("y el nuevo precio es …"+pp.getPrecio()); } if (arg.equals("Soy una fabrica y hay cambio en unidades vendidas")) { Fabrica ff = (Fabrica)o; System.out.println("jeje, en la fabrica hay “+ff.getUnidadesVendidas()+" unidades...."); } } } Patron Observer: el Observer ๏ El Observer es la clase que observa a la clase Observable vista antes. Debe tener un método update() que es invocado en cada cambio de la clase Observable ๏ Se trata de una clase normal, puede tener los atributos y métodos que necesite, en este ejemplo tiene un simple atributo nombre, que ni siquiera se usa :-) En la clase Observer, que esta observando lo que pasa en la Observable vista antes, debe existir un método update() El método recibe dos parámetros: • El objeto de Observable, que trae una copia del objeto observado. Sirve para saber DONDE se ha producido el mensaje. Notar que se hace un casting para convertirlo en el tipo de la clase que se desea evaluar: Producto pp = (Producto)o; • Un objeto generico (llamado aqui args) que trae el “mensaje” desde la clase Observada. Recordar que se trata de un Object, así que puede ser tanto un simple String, como cualquier objeto más complejo. Sirve para saber QUE mensaje se ha producido Si se desea saber qué clase ha producido el mensaje, también se puede preguntar por su tipo con una instrucción como : La clase debe IMPLEMENTAR de Observer if(o instanceof Producto){ ....... }
  • 18. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 18Patron Decorador (Decorator) (I) ๏ El patrón de diseño Decorador asigna responsabilidades adicionales a un objeto dinámicamente, proporcionando una alternativa flexible a la herencia ๏ El ejemplo más claro del patrón dentro del propio JSE de Java es el paquete IO de entrada/salida. En el uso habitual de estas clases, unas recubren a otras siguiendo el patrón de diseño Decorador de tal modo que se van añadiendo nuevas funcionalidad a la clase original con cada nuevo recubrimiento. ๏ Veámoslo con un ejemplo paso a paso: Patrón Decorador //--------------------------------- VEHICULO abstract class Vehiculo { private float precio; public Vehiculo(float precio) { this.precio = precio; } public float getPrecio() { return precio; } public abstract String descripcion(); } //--------------------------------- UTILITARIO class Utilitario extends Vehiculo { public Utilitario(float precio) { super(precio); } @Override public String descripcion() { return "Vehículo utilitario"; } } //--------------------------------- FAMILIAR class Familiar extends Vehiculo { public Familiar(float precio) { super(precio); } @Override public String descripcion() { return "Vehículo familiar"; } } ‣ Queremos crear una serie de clases que representen diferentes vehículos (familiar, utilitario, todoterreno), y calcular el precio de cada uno, según los complementos que lleve instalado cada vehículo (airbag, techo solar, xenon, etc..) ‣ Partimos de entrada de una herencia de clases que tiene por ahora como único valor fijo el precio final del coche ‣ El problema viene ahora, cuando los complementos de cada tipo de coche tienen ademas un coste distinto (no es lo mismo el coste de airbag de un utilitario que en un todoterreno….) ‣ Por lo tanto, lo que nos pide el cuerpo en primera instancia es crear atributos de cada complemento en la clase madre, pero darles valores uno a uno en cada subclase public class PatronDecorador { public static void main(String[] args) { Utilitario u = new Utilitario(12000); Familiar f = new Familiar(24000); System.out.println(u.descripcion()); System.out.println(f.descripcion()); } } consola Vehículo utilitario Vehículo familiar ( Ejemplos extraídos de Oscar Belmonte, de Universitat Jaume I )
  • 19. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 19 ‣ Por lo tanto, lo que nos pide el cuerpo en primera instancia es crear atributos de cada complemento en la clase madre, pero darles valores uno a uno en cada subclase. Claro que esto puede ser tedioso si hay muchos complementos… y además, si en el futuro se añaden complementos a un tipo de coche, hemos de cambiar las clases creadas ‣ Lo que pretende Decorador es que creemos un estructura con una definición básica, y luego, envolvamos dicha definición con otras clases que vayan complementando, mejorando, “decorando” la clase básica inicial ‣ Así que vamos a tomar nuestra clase Vehículo como básica, y vamos a crear los “decoradores” que la completen ‣ Primera aproximación; crear clases por cada complemento existente, que hereden de Vehículo también (para que sean vehículos mejorados) y hacer que dichas clases tengan como atributo un objeto Vehículo (que será el “Vehiculo original” y al que vamos a mejorar): class VehiculoConAirbag extends Vehiculo { // Lo que se crea con esta clase sigue siendo un Vehiculo private Vehiculo vehiculo; // Es es el objeto que va a decorar al vehículo original public VehiculoConAirbag(Vehiculo vehiculo, float precioExtra) { super(precioExtra); // Pasamos a la madre el precio del extra para que lo guarde this.vehiculo = vehiculo; // Recibimos aqui una referencia del Vehiculo que vamos a decorar } @Override public String descripcion() { return vehiculo.descripcion() + // La descripcion del vehiculo decorado es la del vehículo original ", con airbag"; // mas la descripcion de lo que se decora } @Override public float getPrecio() { return vehiculo.getPrecio() + // El precio del vehiculo con su decorado es el del vehículo original super.getPrecio(); // mas el precio extra que se añade ahora (y lo tenia la madre). } } //------------------------------- primera aproximacion Vehiculo vehiculo = new Utilitario(12000); vehiculo = new VehiculoConAirbag(vehiculo, 840); System.out.println(vehiculo.getPrecio()); Así se crea un nuevo vehículo, que recibe como argumento el vehículo original, y lo decora añadiendo funcionalidad. En nuevo vehículo creado lo almaceno en la referencia del …vehículo original Crear vehículo original consola 12840 Patron Decorador (Decorator) (II)
  • 20. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 20 class VehiculoConAirbag extends Vehiculo { private Vehiculo vehiculo; public VehiculoConAirbag(Vehiculo vehiculo, float precioExtra) { super(precioExtra); this.vehiculo = vehiculo; } @Override public String descripcion() { return vehiculo.descripcion() + ", con airbag"; } @Override public float getPrecio() { return vehiculo.getPrecio() + super.getPrecio(); } } class VehiculoConXenon extends Vehiculo { private Vehiculo vehiculo; public VehiculoConXenon(Vehiculo vehiculo, float precioExtra) { super(precioExtra); this.vehiculo = vehiculo; } @Override public String descripcion() { return vehiculo.descripcion() + ", con xenon"; } @Override public float getPrecio() { return vehiculo.getPrecio() + super.getPrecio(); } } ‣ Cuando nos ponemos a hacer nuevas clases para más complementos, nos damos cuenta de que todas son casi iguales entre si, así que sacamos “factor común”, y creamos una superclase para los complementos y subclases para cada uno: abstract class Extra extends Vehiculo { private Vehiculo vehiculo; public Extra(Vehiculo vehiculo, float precioExtra) { super(precioExtra); this.vehiculo = vehiculo; } @Override public float getPrecio() { return vehiculo.getPrecio() + super.getPrecio(); } @Override public String descripcion() { return vehiculo.descripcion(); } } class VehiculoConXenon extends Extra { public VehiculoConXenon(Vehiculo vehiculo, float precioExtra) { super(vehiculo, precioExtra); } @Override public String descripcion() { return super.descripcion() + ", con pintura metalizada"; } } class VehiculoConAirbag extends Extra { public VehiculoConAirbag(Vehiculo vehiculo, float precioExtra) { super(vehiculo, precioExtra); } @Override public String descripcion() { return super.descripcion() + ", con aire acondicionado"; } } Demasiado iguales, haremos mejor una estructura de herencia Patron Decorador (Decorator) (III)
  • 21. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 21 //------------------------------- aproximacion final Vehiculo vehiculo = new Utilitario(12000); vehiculo = new VehiculoConAirbag(vehiculo, 840); System.out.println(vehiculo.descripcion()); System.out.println(vehiculo.getPrecio()); vehiculo = new VehiculoConXenon(vehiculo, 300); System.out.println(vehiculo.descripcion()); System.out.println(vehiculo.getPrecio()); ‣ Solo con la creación de la nueva estructura de herencia, se pueden probar los mismos objetos de la primera aproximación, y funcionan perfectamente ‣ Para el futuro, si se desea añadir mas complementos al coche, solo necesitamos crear la clase del complemento correspondiente !! consola Vehículo utilitario, con airbag 12840.0 Vehículo utilitario, con airbag, con xenon 13140.0 ‣ Como se indicó anteriormente, una uso habitual de este patrón es el uso de la jerarquía de las clases IO de Java. ‣ En este ejemplo podemos ver como la clase básica se “envuelve” en sucesivas clases mejoradas, que ofrecen mas funcionalidad que la clase original InputStream ins = System.in; InputStreamReader isr = new InputStreamReader(ins); BufferedReader br = new BufferedReader(isr); String linea = br.readLine(); System.in hace referencia a la entrada estándar, normalmente teclado El objeto ins (de InputStream) se pasa al constructor de InputStreamReader que devuelve un objeto isr “mejorado”, ya puede leer chars por el canal El objeto isr (de InputStreamReader) se pasa al constructor de BufferedReader que devuelve un objeto br “aun más mejorado”, que ya puede leer lineas completas por el canal Patron Decorador (Decorator) (IV)
  • 22. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Objetos anónimos Objetos anónimos 22 ๏ Esta utilidad ya se ha visto muchas veces probablemente, pero la revisamos ahora para aclarar su naturaleza ๏ Los objetos en Java se crean con la instrucción new. Realmente, se llama al constructor de la clase y con la instrucción new se construye el objeto, y posteriormente, el objeto creado se asigna a una "variable" que almacene el objeto. Se llama objeto a la variable, pero ésta realmente lo que hace es guardar la referencia a donde se almacena la variable. ๏ Realmente, pues, con ejecutar simplemente ya se crea un objeto. Lo que pasa es que la referencia que devuelve, se pierde. ๏ Esto es crear un objeto anónimo, sin darle nombre. ๏ Veamos su utilidad con algunos usos prácticos Autor a1 = new Autor(); Crea el objeto ejecutando el constructor, lo almacena en memoria Heap, y devuelve la referencia a su posición Se crea la "variable" a1 (de tipo Autor), se almacena en el Stack, y guarda la referencia resultado del otro lado del = new Autor(); ArrayList<Autor> lisautores = new ArrayList<>(); lisautores.add(new Autor()); Autor nuevonombre = lisautores.get(0); String as = new Scanner(System.in).nextLine(); new UnaVentanaSwing().lanzar(); Creamos objetos y los metemos en una colección. Una vez en la colección, no necesitamos que tengan un nombre, por que al recuperarlos no recuperamos el nombre, como mucho lo asignamos a otro nuevo También son muy útiles si se desea llamar a un método de una clase, pero no usar la clase para nada más que eso No es anormal crear un ventana, y usar un método para hacerla visible. La ventana interactuará con el usuario, sin necesitar que tenga una variable propia asociada.
  • 23. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Clases internas o anidadas (nested classes) 23 ๏ En java una clase puede tener, entre sus miembros, la declaración de otra clase. A esta clase que se escribe dentro de otra se llama clase anidada o interna, y a la otra, clase contenedora o externa ๏ Desde dentro de la clase interna se puede acceder a todos los miembros de la clase contenedora ๏ Una clase interna puede ser private o protected (las clases normales, no) ๏ Hay varios tipos de clases internas: internas simples (miembro), locales, estáticas y anónimas Clases Internas
  • 24. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 24 ๏ Para crear un objeto de la clase interna fuera de su clase contenedora, hay que usar todo ello siempre que: a) la clase interna no se ha declarado privada b) no se intente crear desde un método static (eso obligaría a que la clase interna fuera estática) ClaseContenedora extObj = new ClaseContenedora(); ClaseContenedora.Interna intObj = extObj.new Interna(); public class InicioDeClaseContenedora { public void hacerCosas() { ClaseContenedora extObj = new ClaseContenedora(); ClaseContenedora.Interna intObj = extObj.new Interna(); } public static void main(String args[]) { ClaseContenedora cc = new ClaseContenedora(); new InicioDeClaseContenedora().hacerCosas(); } } class ClaseContenedora { String IdCC; Interna intEnExt; public ClaseContenedora(String IdCC) { intEnExt = new Interna("Int1"); } public ClaseContenedora() { } public class Interna { String nom; public Interna() { } } } Clases internas miembro Clases internas miembro ๏ Es el caso más sencillo. La clase es como un miembro más de la clase contenedora (pero no static) ๏ Como son miembros de la clase contenedora, sólo existe un objeto de la clase interna cuando exista un objeto de la clase contenedora. ๏ Los nombres de los miembros de la clase contenedora tienen que ser diferentes de los de la clase interna ๏ Una clase interna miembro no puede contener ningún miembro estático ๏ No es posible crear un objeto de la clase interna sin tener un objeto de la clase contenedora. ๏ Dentro de la clase interna se desea hacer una referencia al objeto actual de la clase contenedora se hace mediante NombreClaseContenedora.this. Como crear objetos de la clase interna miembro
  • 25. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 25 ๏ Para crear un objeto de la clase interna fuera de su clase contenedora, hay que usar el constructor tradicional, pero solo dentro del propio método: InternaLocal intlocal = new InternaLocal(); class Contenedora { int a = 44; public void metodoConClase() { int x = 11; final int n = 3; class InternaLocal { public void mostrar() { System.out.println("x vale " + x); System.out.println("a vale " + a); System.out.println("n vale " + n); } } InternaLocal intlocal = new InternaLocal(); intlocal.mostrar(); } public static void main(String args[]) { Contenedora objContenedora = new Contenedora(); objContenedora.metodoConClase(); } } Clases internas locales Clases internas locales ๏ La clase no es un miembro directo de la clase contenedora, sino que se crea dentro de un método de la clase contenedora. Por lo tanto, como cualquier variable local a un método, supone estas características: ‣ su visibilidad se restringe al interior del propio método ‣ la clase interna no puede ser private ni public ni protected ‣ no es posible crear un objeto de la clase interna fuera del propio método donde se declara la clase interna (pues como ya se dijo, su visibilidad se restringe al interior del propio método) ๏ Desde la clase interna se puede acceder a todos los miembros de la clase envolvente, y a los parámetros final del método envolvente. ๏ Puede definir sus propios atributos, pero no pueden ser estáticos. Como crear objetos de la clase interna local
  • 26. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Clases internas static 26 Clases internas static ๏ Una clase interna static que es miembro de la contenedora, pero miembro static, con lo que se comporta como cualquier otro static: - Se puede acceder a la clase interna sin instanciar la clase contenedora (como cualquier otro static) - No tiene acceso a los miembros de la clase contenedora, salvo que estos también sean static ๏ Una clase interna static puede declarar su propios miembros, estáticos o no. class Contenedora { static class InternaEstatica { public void pintar() { System.out.println(“En la clase interna estática"); } } public static void main(String args[]) { Contenedora.InternaEstatica intstatic = new Contenedora.InternaEstatica(); intstatic.pintar(); } } Como crear objetos de la clase interna static ๏ Para crear un objeto de la clase interna static fuera de su clase contenedora, basta con usar : Contenedora.InternaEstatica intstatic = new Contenedora.InternaEstatica();
  • 27. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Clases anónimas (I) 27 Clases anónimas ๏ Una clase anónima es una clase interna que se crea sin nombre, y que crea un único objeto de la clase ๏ Es útil para crear una clase sin tener que heredar expresamente de otra, cuando solo necesitamos un objeto ๏ Se utiliza mucho por ejemplo con listeners en interfaces gráficas o con interfaces funcionales ๏ Se pueden crear de dos formas: class MiClaseConHilo { public static void main(String[] args) { Thread hilo = new Thread() { public void run() { System.out.println("hola!"); } }; hilo.start(); } } 1 Clase anónima que extiende de otra clase o de otra interfaz. abstract class Comida{ abstract public void mostrar() ; } class PruebaInternas { public static void main(String[] args) { Comida com = new Comida() { public void mostrar() { System.out.println("Sosa !"); } }; System.out.println(com instanceof Comida); com.mostrar(); } } 2 Clase anónima como parámetro de un método interface IPerro { String ladra(); } class PruebaPerro { public void haciendoruido(IPerro p) { System.out.println(p.ladra()); } public static void main(String args[]) { PruebaPerro pp = new PruebaPerro(); pp.haciendoruido( new IPerro() { public String ladra() { return "GUAU !"; } }); } } boton1.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent arg0) { System.out.println("Pulso el boton 1"); } }); Si un método recibe un objeto de una clase o interfaz como argumento, podemos pasar dicho objeto en el argumento, o también podemos pasar como argumento una clase anónima, con la descripción de su contenido Consiste en definir la clase justo tras la llamada al constructor, entre llaves, en vez de hacerlo en un fichero separado
  • 28. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado 28 ๏ Una clase anónima puede acceder sin problema a los miembros de la clase contenedora ๏ Una clase anónima accede a las variables locales de la clase contenedora si estos son declarados final ๏ Una clase anónima no puede tener inicializadores static. ๏ La clase contenedora, como en el resto de casos de clases internas, no tiene acceso directo a los miembros y variables de la clase anónima. Características de las clases anónimas ๏ Una clase normal puede implementar muchas interfaces, pero una anónima solo una ๏ Una clase normal puede implementar y extender a la vez, pero una anónima solo una de ambas cosas, no las dos ๏ Una clase anónima no puede tener constructor (no tiene nombre, raro sería el constructor …) Como acceder desde una anónima a miembros de contenedora y viceversa Clases anónimas (II)
  • 29. TemariodecursoJavaSE©IñakiMartín 7.- Clases y objetos 29Clases Internas: static, miembro, locales, anónimas / CLASE EXTERNA class Formula1{ String escuderia; static double presupuesto ; double deudas; ; // CLASE INTERNA MIEMBRO (NO ESTATICA) class Piloto{ String nombrePiloto; int edadPiloto; public void pintarDatos(){ System.out.println(escuderia+": "+(presupuesto-deudas)); } } // CLASE INTERNA ESTATICA static class Motor{ int potencia; static int numCilindros; public double redimiento(){ return presupuesto/potencia; } } public void metodoConClase(){ // CLASE LOCAL class ClaseDelMetodo{ int id; } ClaseDelMetodo s = new ClaseDelMetodo(); } public void informacion(){ System.out.println(escuderia+": Piloto: "+ Motor.numCilindros); System.out.println(nombrePiloto); Piloto p = new Piloto(); p.edadPiloto=23; Motor m = new Motor(); m.potencia=423; ClaseDelMetodo s = new ClaseDelMetodo(); } } class MiClaseConHilo { public static void main(String[] args) { Thread hilo = new Thread() { public void run() { System.out.println("hola!"); } }; hilo.start(); } } CLASE INTERNA ESTÁTICA Solo puede acceder a los miembros estáticos de la clase contenedora. Puede definir sus propios atributos, estáticos o no. CLASE INTERNA MIEMBRO (NO ESTÁTICA) Puede acceder a todos los miembros de la clase contenedora. Puede definir sus propios atributos, pero no pueden ser estáticos. CLASE LOCAL (DENTRO DE UN METODO) Puede acceder a todos los miembros de la clase contenedora, y a los parámetros final del método contenedor. Puede definir sus propios atributos, pero no pueden ser estáticos. VISIBILIDAD DE LOS MIEMBROS DE LAS CLASES INTERNAS No se puede acceder a los miembros de una clase interna desde su clase contenedora, salvo que; - sean estáticos y se acceda de modo estático con el nombre de la clase. - Se creen instancias de las clases internas en la clase contenedora, salvo en el caso de la clase local, de la que solo pueden crearse instancias dentro del mismo método donde se declara CLASE ANÓNIMA Puede acceder a todos los miembros de la clase contenedora, y a los parámetros final del método envolvente. Puede definir sus propios atributos, pero no pueden ser estáticos. No puede tener constructor
  • 30. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Metodos default e interfaz funcional Métodos default 30 ๏ Java 8 incluye como novedad la posibilidad de que las interfaces tengan código, algo que hasta entonces estaba vetado ๏ Ahora, en una interfaz se pueden añadir métodos default, que tienen estas características: - Tienen que tener su implementación escrita, como cualquier método normal no abstracto - A la hora de implementar la interfaz, podemos hacer varias cosas con el/los métodos default: ‣ No hacer nada, con lo que se "heredan" tal y como están. ‣ Reescribirlos y cambiar su comportamiento. ‣ Redeclararlos como método abstracto, que necesitaría implementación de las siguientes subclases. ๏ Estos métodos son útiles cuando haya un desarrollo ya creado, con muchas clases implementando una interfaz, que nos interese hacer crecer. Con un método default pueden convivir las antiguas clases con las futuras a crear ๏ Es solo un concepto, no un nuevo elemento. Aparece como concepto en la version Java 8 ๏ Son interfaces que tienen solamente un método abstracto, es decir puede implementar uno o más métodos default, pero deberá tener forzosamente un único método abstracto. ๏ Se escriben como una interfaz normal, no necesitan definirse de modo alguno. Es solo un concepto. ๏ Son especialmente útiles con expresiones Lambda ๏ Para asegurarnos de que estamos definiendo correctamente una interface funcional, podemos añadir la anotación @FunctionalInterface  Interfaces funcionales
  • 31. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Expresiones Lambda (Java 8) 31 ๏ Las expresiones lambda son métodos anónimos, es decir, métodos que no necesitan una clase. ๏ Se deben usar con Interfaces Funcionales En realidad se pueden usar con cualquier CLASE ABSTRACTA (o INTERFAZ) que tengan SOLO un método abstracto ๏ La expresión lambda contiene la implementación del método abstracto de la Interfaz Funcional. ๏ Valen por ejemplo para resumir codigo en llamadas a clases internas (amen de otras cosas) ๏ Su formato normal es ( parámetros ) -> {  cuerpo } i. El operador lambda (->) separa la declaración de parámetros de la declaración del cuerpo de la función. ii. Parámetros: ‣ Cuando se tiene un solo parámetro no es necesario utilizar los paréntesis. ‣ Cuando no se tienen parámetros, o cuando se tienen dos o más, es necesario utilizar paréntesis. iii. Cuerpo de lambda: ‣ Cuando el cuerpo de la expresión lambda tiene una única línea no es necesario utilizar las llaves y no necesitan especificar la cláusula return en el caso de que deban devolver valores. ‣ Cuando el cuerpo de la expresión lambda tiene más de una línea se hace necesario utilizar las llaves y es necesario incluir la cláusula return en el caso de que la función deba devolver un valor . Lamba Expresions
  • 32. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Expresiones Lambda (Java 8) 32 ๏ Cuando se crea una expresión lambda, ésta se convierte en un "objeto", que se puede asignar a un valor de una Interfaz Funcional interface IPruebaLambda { // un solo metodo abstracto int sumaIntYString(int num1, String num2); } // Formato lambda en modo instrucción. Puede hacerse más resumido IPruebaLambda objIPL = (numero, cadena) -> { return numero + Integer.parseInt(cadena); }; // Formato lambda en modo expresion IPruebaLambda objIPLDos = (int numero, String cadena) -> numero + Integer.parseInt(cadena); // No es necesario el tipo de dato en los parámetros, el compilador lo infiere automaticamente. IPruebaLambda objIPLTres = ( numero, cadena) -> numero + Integer.parseInt(cadena); System.out.println(objIPL.sumaIntYString(3,"345")); System.out.println(objIPLDos.sumaIntYString(3,"345")); System.out.println(objIPLTres.sumaIntYString(3,"345")); // Usamos aun la misma interfaz IPruebaLambda IPruebaLambda objIPLDuplicado = ( numero, cadena) -> (numero*2) + (Integer.parseInt(cadena)*2); System.out.println(objIPLDuplicado.sumaIntYString(3,"345")); ๏ Importante: el desarrollo del método anónimo puede ser diferente para cada objeto de la interfaz que se quiera crear consola 348 348 348 consola 696 Interfaz Funcional: de ella solo tenemos claro que hay un método que tiene dos parámetros. Lo que haga el método se puede escribir en una expresión lambda, tantas veces y tan distintas como se quiera Ejemplo de desarrollo de la interfaz con expresiones lambda Ejemplo de desarrollo diferente de la interfaz con expresiones lambda
  • 33. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Expresiones Lambda (Java 8) 33 ๏ Ejemplo de uso de expresiones Lambda con Hilos. ๏ Los hilos lanzados por la clase Thread son objetos de herederos de la interfaz Runnable, que solo tiene un método abstracto, el run() de los hilos. Esta interfaz puede actuar de interfaz funcional, asi que se puede implementar el método run como método anónimo con una expresión lambda: // EJEMPLO 1 class EjemploHiloConLambda { public static void main(String[] args) throws InterruptedException { Runnable objDeMetodoRun = () -> { System.out.println("Estoy dentro del Run de un hilo"); }; Thread MiHilo = new Thread(objDeMetodoRun); MiHilo.start(); } } // EJEMPLO 2 class EjemploHiloConLambda2 { public static void main(String[] args) throws InterruptedException { Thread MiHilo = new Thread(MétodoQueDevuelveUnRunnable()); MiHilo.start(); } static Runnable MétodoQueDevuelveUnRunnable() { Runnable objDeMetodoRun = () -> { System.out.println("Estoy dentro del Run de un hilo"); }; return objDeMetodoRun; } } // EJEMPLO 3 class EjemploHiloConLambda3 { public static void main(String[] args) throws InterruptedException { Thread MiHilo = new Thread(MétodoQueDevuelveUnRunnable()); MiHilo.start(); } private static Runnable MétodoQueDevuelveUnRunnable() { return () -> { System.out.println("Estoy dentro del Run de un hilo"); }; } } consola Estoy dentro del run de un hilo Crear el método run como anónimo, y asignarlo a un objeto de la interfaz Runnable Crear el hilo con el objeto de Runnable, que es lo que necesita Thread en el constructor Ahora Thread lo que recibe en el constructor es lo que devuelve un método nuevo (que devuelve un Runnable) Este es el método nuevo, que crea el mismo objeto Runnable del ejemplo 1, y lo devuelve con un return normal Por pura sustitución, ponemos dentro del método un return, que devuelve lo que valia antes objDeMetodoRun
  • 34. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Expresiones Lambda (Java 8) 34 // Implementacion de escuchador SIN clase anonima class ProbarListenerSinAnonima { public static void main(String args[]) { JButton button = new JButton("Pusar aqui"); // Aqui se añade el eescuchador al boton como un nuevo objeto de mi clase escuchadora miClaseActionListener mial = new miClaseActionListener(); button.addActionListener(mial)); } } class miClaseActionListener implements ActionListener { public void actionPerformed(ActionEvent evt) { System.out.println("ha pulsado el boton!"); } } // Implementacion de escuchador CON clase anonima class ProbarLambdaListener { public static void main(String args[]) { JButton button = new JButton("Pusar aqui"); // Aqui se añade la clase anonima como si fuera el objeto de mi escuchador button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { System.out.println("ha pulsado el boton!"); } }); } } // Implementacion de escuchador CON METODO LAMBDA class ProbarLambdaListener { public static void main(String args[]) { JButton button = new JButton("Pusar aqui"); // Como ActionListener es una interface que tiene solo un metodo, actionPerformed(), // es una interface funcional, asi que es idonea para usar una expresion Lambda button.addActionListener(e -> System.out.println("ha pulsado el boton!")); } } ๏ Ejemplo de uso de expresiones Lambda con Listeners de Swing (o Android). Sin Lambda, y sin clase anónima Sin Lambda, y con clase anónima Con Lambda
  • 35. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Uso de var en Java 10 35 public class PruebasVar { public static void main(String[] args) { var list = new ArrayList<>(); // INFIERE QUE list ES UN ARRAYLIST int x = 12; if (x % 2 == 0) { var z = 2; // INFIERE QUE list ES UN INT var cla = new ClavoSinPunta(); //cla es un CLAVOSINPUNTA, no un CLAVO } } } class Clavo { } class ClavoSinPunta extends Clavo { } ๏ Desde la version 10 de Java se puede usar var para declarar variables locales, y el compilador infiere, según el contenido que tenga, que tipo de dato va a tener la variable: Ejemplos de uso: Usos permitidos Uso de var en java public class PruebasVar{ var z = 2; // NO SE PUEDE USAR VAR EN ATRIBUTO DE CLASE public static void main(String[] args) { var algo = null; // NO SE PUEDE INICIALIZAR UN VAR A NULL var z = () -> {}; // NO SE PUEDE USAR VAR CON EXPRESIONES LAMBDA } public void sumar(var x) { // NO SE PUEDE USAR VAR EN PARAMETRO DE METODO } } Usos prohibidos
  • 36. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Creación de JAR 36 ๏ Una aplicación java se puede empaquetar en un fichero único, que puede ser ejecutado directamente desde el sistema operativo, sin usar un IDE como Eclipse o Netbeans. Explicamos como hacerlo con varios IDE: Uso de var en java (Click derecho sobre el proyecto) File -> Export -> Java -> JAR File Seleccionar el proyecto a comprimir y el nombre y directorio donde crearlo. Es importante que haya permisos en el directorio. Seguir con Next, no con Finish crear JAR desde ECLIPSE Seguir con Next, no con Finish, hasta llegar a esta pantalla, “JAR Manifest Specification”. En ella es importante que esté marcada la opción Generate the manifest File, y que esté seleccionada la clase que contiene el método main de inicio de proyecto Acabar con Finish. 1 2 3
  • 37. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Creación de JAR 37 File -> Project Structure Artifacts -> (+) -> JAR -> From modules… Seleccionar proyecto (viene por defecto) y clase que contiene el main (no olvidar). Resto de opciones no tocarlas Con lo anterior se crea un artefacto, que es como un generador de elementos. Ahora vamos a generar el jar de verdad. BUild-< Build artifacts Seleccionamos el artefacto :jar que haya, y la opción Build Con lo anterior se crea un directorio classes, a la misma altura que el src del proyecto, que tiene dentro el fichero .jar con el proyecto Se puede invocar a este .jar directamente fuera del IDE y ver como se ejecuta directamente (si es una aplicación UI, con ventanas) o se puede ejecutar desde una terminal, con la orden $ java -jar nombredeljar.jar crear JAR desde INTELLIj 1 2 3 4 5 6
  • 38. TemariodecursoJavaSE©IñakiMartín
 21.- JSE Avanzado Creación de JAR 38 (Con el proyecto seleccionado en el Package Explorer) FIle - > Project Properties En opción Packaging, marcamos “Build Jar after Compiling” . SI el proyecto tiene librerías externas, marcar también “Copy Dependent Libraries” crear JAR desde NETBEANS 1 2 3 Finalizar con OK. Luego se hace ejecutar el proyecto o se solicita “Build” o “Clean and build” El fichero jar se deja por defecto en la carpeta “dist” del proyecto, aunque se puede modificar en las propiedades, en esta caja