• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Programacion en Java
 

Programacion en Java

on

  • 643 views

Curso de Programación en Java.

Curso de Programación en Java.
Introducción a Java, Ficheros, Redes y JDBC

Statistics

Views

Total Views
643
Views on SlideShare
643
Embed Views
0

Actions

Likes
0
Downloads
47
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Programacion en Java Programacion en Java Presentation Transcript

    • Programación en JavaJorge Guilló – jguillo@gmail.com
    • Contenido Java  Introducción  Primer programa  Programación básica  Programación orientada a objetos  Excepciones  Archivos JAR API Java  Fechas y cadenas  Colecciones  Tratamiento de ficheros  Redes  Programación multihilo Acceso a datos (JDBC)  Arquitectura  Conexiones  Comandos y consultas  Transacciones
    • Introducción a Java Origen y arquitectura de Java Yo soy Duke!
    • Origen de Java Deriva de C y C++ Creado por James Gosling y otros ingenieros de Sun Microsystems Se creó en 1991 en sólo 18 meses  Primero se llamó Oak  Se creó para dispositivos electrónicos ante la necesidad de crear un lenguaje independiente de la plataforma En 1994 cambia su orientación hacia Internet  Se utiliza el nombre Java JDK 1.0 aparece en 1996
    • Tipos de Aplicaciones en Java Con Java se pueden hacer varios tipos de aplicaciones:  Aplicaciones normales  Applets  Componentes JavaBeans  Servlets  JSP  Enterprise Java Beans (EJB)
    • Código binario (ByteCode) Genera bytecode, no es código ejecutable La máquina virtual Java (JVM) ejecuta el bytecode Se necesita una JVM para cada plataforma Lento pero seguro Compilador Just-In-Time (JIT) La JVM utiliza cargadores de clases para obtener los bytecodes del disco o de la red
    • Características de Java Simple  Gestión de memoria Orientado a Objetos  Arquitectura neutral El núcleo API  Interpretado y de Robusto alto rendimiento Multihilo  Distribuido
    • Ediciones de Java 2 JDK Micro Edition (J2ME)  Para dispositivos electrónicos JDK Standard Edition (J2SE)  Para ordenadores de sobremesa JDK Enterprise Edition (J2EE)  Para empresas  Java Server Pages  Servlets  Java support for XML  Enterprise JavaBeans (EJB)
    • El Kit de desarrollo de Java(JDK Standard Edition) Gratis Versiones del JDK: 1.0, 1.1, 1.2, 1.3, 1.4, 1.5 Se compone de las librerías estándar (clases o APIs) y utilidades:  Compilador: javac miFichero.java  Intérprete: java miFichero.class appletviewer miFichero.class  Documentador: javadoc miFichero.java
    • Entorno de ejecución (JRE) Gratis Permite ejecutar cualquier aplicación Java en el cliente Se compone de las librerías estándar (clases o APIs) y el intérprete
    • Java Plug-in Hace que los applets y los componentes JavaBeans los ejecute el JRE que tenga instalado el cliente en vez de la máquina virtual del navegador Tiene como ventaja el poder utilizar las novedades de la última versión Instalación automática, aparece un icono en el panel de control Para que funcione hay que cambiar las etiquetas de los applets con la utilidad HtmlConverter.bat del JDK
    • La máquina virtual Java (JVM) CPU por software que tiene los bytecodes por juego de instrucciones Los bytecodes son de la forma: <opcode><...parámetros> La JVM verificará aquellos bytecodes que hayan atravesado la red El intérprete traduce los bytecodes a instrucciones específicas del sistema operativo/hardware Escrita en C, C++ o ensamblador
    • Rendimiento JVM más lenta que los ejecutables tradicionales:  El proceso de verificación lleva su tiempo  Conversión de los bytecodes a instrucciones de máquina nativa  Múltiples chequeos de seguridad  Las instrucciones de Java son código del tamaño de un byte  Java se ha implementado como una máquina de pila en la memoria  Garbage collection
    • Seguridad No hay punteros  Garbage Collection Hay tres componentes principales:  El verificador de código  Se asegura que los bytecodes se ajustan a la especificación de JVM.  El cargador de clases  Recupera las clases de la red, guardando las de cada servidor en un sitio diferente para evitar interferencias  El gestor de seguridad  Chequea la política de seguridad, es decir, se determina que actividades puede realizar la JVM y bajo que circunstancias
    • Entornos de programación JDK + editor  IDE completo  Notepad  Eclipse  TextPad  NetBeans  UltraEdit  Borland JBuilder  JEdit  IBM Websphere  Emacs  Oracle JDeveloper  BEA WebLogic Workshop  Xinox JCreator
    • Primer programa en Java// fichero HolaMundo.java // fichero HolaMundo.javaclass HolaMundo { class HolaMundo { public static void main(String args[]) public static void main(String args[]) {{ System.out.println("Hola mundo!"); System.out.println("Hola mundo!"); } // fin de main() } // fin de main()} // fin de class HolaMundo } // fin de class HolaMundo Uy! Un HolaMundo! Qué original....
    • Primer programa en JavaCompilación Código fuente HolaMundo.java javac HolaMundo.java ___________  ___________  -d <dir.destino> class Ho  -sourcepath <dir.fuentes> Esto estará en un public vo  -classpath <dir.librerias> segundito…  Genera código intermedio 100101 interpretable por la 011101 máquina virtual HolaMundo.class (bytecode) Bytecode
    • Primer programa en JavaEjecución o! mu nd java HolaMundo Hola  -classpath <dir.clases> Ejecuta la clase HolaMundo.class en la máquina virtual  Busca un método public static void main(String args[]) dentro de la clase y lo ejecuta Se debe proporcionar la ruta de acceso a todas las clases que se utilicen dentro del programa
    • Programación Java Programación básica
    • Ficheros java Una sola clase pública por fichero Al compilar se genera un .class por cada clase (pública o privada)
    • Comentarios Una línea  // Comentario Multilinea  /* Comentario  Comentario */ Comentario para documentación  /** * Comentario JavaDoc */
    • Variables Declaración de variable  int i; Declaración múltiple  int a,b,c; Asignación de variable  i = 5; Declaración + asignación  int i = 5;
    • Visibilidad de variables Los bloques de código (llaves) definen el alcance de las variables void funcion(int x) { void funcion(int x) { int y = 5; int y = 5; if (x == y) { if (x == y) { int z = x + y; int z = x + y; }} System.out.println(x); System.out.println(x); System.out.println(y); System.out.println(y); System.out.println(z); // Error System.out.println(z); // Error }}
    • Tipos de datos Básicos (por valor)  boolean  byte, short, int, long  float, double  char (Unicode) Clases (String es una clase) Matrices (arrays)
    • Expresiones Literales  Operadores  Numéricos  Aritméticos + - * / %  4, 071, 0xFF,  -4.5, 5e6  Comparación == != > >= < <=  3L, 4.5F  Lógicos  Booleanos & && | || ^ ! true false De Bit    Carácter & | ^ ~ << >> >>>  A  Asignación  Cadena = ++ -- += -= ...  "Hola"  Condicional ?:  "DosnLineas"
    • Conversión de tipos Ensanchamiento: Conversión a un tipo más grande  La conversión es automática  long l = 65; Estrechamiento: Conversión a un tipo más pequeño  Se necesita utilizar el operador de cast  int i = (int)l;
    • Sentencias condicionales switch (i) { switch (i) {if (a>b) { if (a>b) { case 0: case 0: // Código // Código //Código} //Código } break;else { else { break; // Código default: default: // Código}} //Código //Código break; break; }} ¿.. ?
    • Buclesfor (i=0;i<10;i++){ for (i=0;i<10;i++){ do { do { // Código // Código // Código} // Código } } while (i>0); } while (i>0);while (i > 0) { while (i > 0) { // Código break; break; // Código}  Terminar bucle }  Terminar bucle continue; continue;  Siguiente  Siguiente iteración iteración
    • Matrices Las matrices son objetos de la clase Array Declaración:  String[] palabras;  String palabras[]; Creación:  String[] palabras = new String[5];  String[] palabras = { "Hola", "mundo" } Acceso a elementos:  palabras[0] = "Adiós"; Obtener tamaño:  int tam = palabras.length; Los índices válidos van desde 0 a .length - 1
    • Matrices multidimensionales Se utilizan matrices de matrices  int[][] matriz = new int[4][4];  matriz[0][0] = 3; .length devuelve el tamaño de la primera componente, no el tamaño total de la matriz Se pueden crear matrices no uniformes  int[][] matriz = new int[3][];  matriz[0] = new int[2];  matriz[1] = new int[3]; 0: 1:  matriz[2] = new int[1]; 2:
    • Programación Java Programación orientada a objetos
    • Clases La clase es el núcleo de Java Una clase define un nuevo tipo de dato Una clase es una plantilla para un objeto Un objeto es una instancia de una clase A las propiedades y los métodos se les llama miembros de la clase
    • Forma general de una claseclass NombreClase { class NombreClase { tipo variable1; tipo variable1; tipo variable2; tipo variable2; tipo metodo1(parámetros) tipo metodo1(parámetros) {{ // cuerpo del método // cuerpo del método }} tipo metodo2(parámetros) tipo metodo2(parámetros) {{ // cuerpo del método // cuerpo del método }}}}
    • Ejemplo de clase La clase más pequeña podría ser así:class MiClase { class MiClase { // la máquina virtual llama al método main() // la máquina virtual llama al método main() public static void main (String args[]) { public static void main (String args[]) { System.out.println(“Hasta luego System.out.println(“Hasta luego Lucas”); Lucas”); }}}} El punto de entrada a la aplicación es a través del método main( ) que es llamado por la JVM
    • Una clase sencilla Creación de la clase class Caja { class Caja { double ancho; double ancho; double alto; double alto; double fondo; double fondo; }} Creación del objeto a partir de esa clase Caja objCaja; Caja objCaja; objCaja = new Caja(); objCaja = new Caja(); // también: Caja objCaja = new Caja(); // también: Caja objCaja = new Caja(); objCaja.ancho = 20.4; objCaja.ancho = 20.4; objCaja.alto = objCaja.fondo = 30.3; objCaja.alto = objCaja.fondo = 30.3;
    • Referencias a objetos Las variables de tipo objeto almacenan referencias  El objeto se almacena en el "montón" (heap)  Una referencia nula (p.ej. antes de crear el objeto) se indica con la palabra clave null La asignación entre objetos copia la referencia, no el contenido del objeto  Point p1;  p1 = new Point(10,10); HEAP  Point p2; PILA  p2 = p1; Point  p1.x = 5 p1: x=10 y=10 x=5 y=10 p2:
    • Nomenclatura Java Por convención, en Java se utilizan las siguientes reglas para identificadores:  Clases e interfaces: Mayúsculas cada palabra  class MiClaseRectangulo {...}  Miembros, variables y parámetros: Minúsculas la primera palabra, mayúsculas las siguientes  void escribeEntero(int entero) {...}  int numLinea;  Paquetes: Todo minúsculas (no se suele utilizar más de una palabra)  package com.miempresa.proyecto;  Constantes: Todo mayúsculas (con subrayados entre palabras)  final double PI = 3.141592;  final int VELOCIDAD_LUZ = 299792458;
    • Métodos Forma general de un método: tipo nombreMetodo(tipo1 param1, tipo2 param2) { // cuerpo del metodo }  Si no devuelve resultado se indica void como tipo del método Para devolver un valor: return valor; Ejemplo: double volumen( ) { return ancho * alto * fondo; }
    • Constructores Método que ejecuta el operador new Si no existe, java crea uno por defecto Para tareas de inicialización Ejemplo: Caja( ) { Caja( ) { ancho = alto = fondo = 0; ancho = alto = fondo = 0; } }
    • this Para acceder al propio objeto, se utiliza this  Acceso a miembros con nombre conflictivo int valor; int valor; int setValor (int valor) { int setValor (int valor) { this.valor = valor; this.valor = valor; }}  Llamada a otros constructores Caja(Caja c) { Caja(Caja c) { this(c.alto,c.ancho,c.fondo); this(c.alto,c.ancho,c.fondo); }}  Pasar el propio objeto como parámetro void Guardar(ArrayList lista) { void Guardar(ArrayList lista) { lista.add(this); lista.add(this); }}
    • Sobrecarga de métodos Dos o más métodos dentro de la misma clase con el mismo nombre y distintos parámetros float incremento (float valor) { float incremento (float valor) { return Math.abs(valor) * 1.16; return Math.abs(valor) * 1.16; }} double incremento (double valor) { double incremento (double valor) { return Math.abs(valor) * 1.16; return Math.abs(valor) * 1.16; }} También se pueden sobrecargar los constructores Cuando se invoca un método sobrecargado, Java utiliza el tipo y/o el nº de argumentos para saber a qué método llamar
    • Parámetros Se pueden pasar objetos a los métodos como parámetros Un tipo simple se pasa por valor  (byte, short, int, long, char, float, double, boolean) Un objeto se pasa por referencia  (arrays, Strings, etc.) Los métodos pueden devolver objetos
    • Control de acceso Modificadores de acceso de los miembros:  public  Los miembros pueden ser accedidos desde cualquier parte del programa  private  Los miembros sólo pueden ser accedidos desde dentro de la misma clase  protected  Los miembros pueden ser accedidos desde otro paquete pero a clases que sean subclases directas de su clase  nada (por defecto)  Los miembros sólo pueden ser accedidos desde dentro del mismo paquete
    • Protección de acceso  Acceso a miembros de una clase:Desde private nada protected public (package)Misma clase Sí Sí Sí SíSubclase del mismo paquete No Sí Sí SíNo subclase del mismo paquete No Sí Sí SíSubclase de diferente paquete No No Sí SíNo subclase de diferente paquete No No No Sí
    • Métodos accesores(propiedades) Las variables de instancia se suelen declarar privadas Se añaden métodos getXXX() y setXXX() para obtener y establecer el valor de dichas variables public class Propiedades { public class Propiedades { private int valor; private int valor; public int getValor() { public int getValor() { return this.valor; return this.valor; }} public void setValor(int valor) { public void setValor(int valor) { this.valor = valor; this.valor = valor; }} }}
    • static Métodos static:  Se puede llamar a un método static o a una variable static sin crear el objeto de la clase Variables static:  Las variables static actúan como variables globales (todas las instancias de la clase comparten la misma variable static) Bloques de código static:  Es lo primero que se ejecuta, incluso antes que el constructor
    • Método main Una aplicación Java necesita contener al menos una clase ejecutable Para poder ejecutar una clase Java, ésta debe definir un método main con la siguiente signatura:  public static void main (String arg[]) {...}  Debe ser público, accesible desde fuera del paquete  Debe ser estático, ya que no se va a crear ningún objeto para lanzar el método  No devuelve ningún resultado (void)  Recibe como parámetro un vector de cadenas, que corresponden a los argumentos de línea de comandos que se proporcionan a la aplicación al ejecutarla
    • Herencia Se define una clase padre (superclase) que da características comunes (variables y métodos) a todas sus clases hijas (subclases) Se utiliza la palabra clave extends No hay limite en el nivel de profundidad de la herencia Java no soporta herencia múltiple
    • Ejemplo de herenciaclass A { class A { int i, j; int i, j; void verij() { void verij() { System.out.println(“i: “ + i + “, j: “ + j); System.out.println(“i: “ + i + “, j: “ + j); }}}}class B extends A { class B extends A { int k; int k; void verijk() { void verijk() { System.out.println(“i: “ + i + “, j: “ + j System.out.println(“i: “ + i + “, j: “ + j + “, k: “ + k); + “, k: “ + k); }}}}
    • Conversión de referencias Se puede asignar una referencia a un objeto a una referencia de un tipo compatible  Clase en la jerarquía de clases base  Interfaz implementado por el objeto Ensanchamiento: Conversión de un tipo derivado a un tipo base o interfaz  Se puede realizar la asignación directamente  String s = "Hola";  Object obj = s; Estrechamiento: Conversión a un tipo derivado  Se debe utilizar el operador de cast  s = (String)obj;
    • super Acceso a miembros de la clase base  Llamar al constructor de la superclase: super(parámetros)  Si no se llama explícitamente a un constructor de la clase base, Java añade la llamada al constructor por defecto super()  Acceder a un miembro de la superclase: super.miembro
    • Sobreescritura de métodos Un método de una subclase que tiene el mismo nombre y parámetros que la superclase  Cambia la implementación proporcionada por la clase base Sobrecarga de métodos: Varios métodos con el mismo nombre pero diferentes parámetros
    • Polimorfismo Se llama polimorfismo a tener un mismo método con distintas implementaciones Se consigue a través de la sobreescritura de los métodos Vehiculo v = new Moto(); Vehiculo v = new Moto(); v.Frenar( ); v.Frenar( ); v = new Coche(); v = new Coche(); v.Frenar( ); v.Frenar( ); Las llamadas son iguales, pero la implementación que se ejecuta es distinta
    • Clases abstractas Proporcionan una implementación parcial de la clase Los métodos no implementados se declaran como abstract y la clase también abstract tipo nombreMetodo(parámetros); Una subclase de una clase abstracta debe implementar todos los métodos abstractos o declararse como abstracta No se pueden crear objetos de clases abstractas
    • final Usos de la palabra clave final:  Para definir constantes final int cancel = 2; final int cancel = 2;  Para evitar la sobreescritura final void metodo( ) { final void metodo( ) { // cuerpo del método // cuerpo del método }}  Para evitar la herencia final class A { final class A { // cuerpo de la clase // cuerpo de la clase }}
    • La clase Object Es una clase definida por Java Todas las demás clases son subclases de Object Métodos importantes de la clase Object:  clone( ) para clonar un objeto  equals( ) para comparar contenido de objetos  toString( ) para visualizar un objeto
    • Asignar tipos primitivos a Object Para cada tipo primitivo, existe una clase asociada que lo representa.  Para poder asignar un valor de tipo primitivo a una variable de tipo Object hay que construir un objeto de la clase correspondiente  Se puede recuperar el valor primitivo a partir del objeto int i = 5; int i = 5; Object obj = new Integer(i); Object obj = new Integer(i); Integer objInt = (Integer)obj; Integer objInt = (Integer)obj; i = objInt.intValue(); i = objInt.intValue();
    • Novedades JDK 1.5 Autoboxing: Conversión automática de tipos primitivos a sus clases correspondientes Integer Integer i = 3; i = 3; int j = int j = i; i;
    • Conversión número-cadena Los objetos de encapsulación de tipos primitivos proporcionan además métodos estáticos de conversión a y desde cadena Convertir número a String String st = String.valueOf(2); String st = String.valueOf(2); String st = Double.toString(2); String st = Double.toString(2); String st = Float.toString(2); String st = Float.toString(2); String st = Long.toString(2); String st = Long.toString(2); String st = Boolean.valueOf("true").toString(); String st = Boolean.valueOf("true").toString();  Convertir String a número double d = Double.valueOf("2").doubleValue(); double d = Double.valueOf("2").doubleValue(); float f = Float.valueOf("2").floatValue(); float f = Float.valueOf("2").floatValue(); long l = Long.valueOf("2").longValue(); long l = Long.valueOf("2").longValue(); double d1 = Double.parseDouble("2"); double d1 = Double.parseDouble("2"); float f = Float.parseFloat("2"); float f = Float.parseFloat("2"); long l = Long.parseLong("2"); long l = Long.parseLong("2");
    • Interfaces Permite abstraer completamente la interfaz de una clase utilizando la palabra clave interface Una clase puede implementar cualquier número de interfaces a través de la palabra clave implements Cada clase que implemente una interfaz, debe implementar todos los métodos de la interfaz Si una clase implementa una interfaz pero no implementa todos los métodos, tiene que ser abstract Se pueden utilizar interfaces para importar constantes. PERO NO ES RECOMENDABLE Las interfaces se pueden extender
    • Herencia vs Interfaces Implementación Herencia de clases de interfaces Se pueden implementar todos losSólo se puede tener una clase base interfaces que se quieraUna clase base puede tener cualquier Un interfaz sólo puede tener constantes,tipo de miembros variables estáticas y métodosLa clase base puede proporcionar Un interfaz sólo aporta la definición delimplementación a los métodos método, no su implementaciónSe puede crear directamente un objeto No se puede crear directamente unde la clase base objeto de tipo interfaz(salvo clases abstractas)
    • Novedades JDK 1.5 Enumerados:  enum Color { rojo, azul, verde, amarillo }  Son clases, por lo que se les pueden añadir variables y métodos public enum Moneda { public enum Moneda { pela(1), duro(5), chapa(25), libra(100); pela(1), duro(5), chapa(25), libra(100); Moneda(int value) { this.value = value; } Moneda(int value) { this.value = value; } private final int value; private final int value; public int value() { return value; } public int value() { return value; } }} import static: Permite acceder a miembros estáticos de una clase sin el nombre de la clase import static java.lang.System.*; import static java.lang.System.*; class Consola { class Consola { public void Escribir(String s) { public void Escribir(String s) { out.println(s); out.println(s); }} }}
    • Paquetes Es un conjunto de clases agrupadas bajo un nombre Permiten dar a 2 clases el mismo nombre siempre que estén en diferentes paquetes Para crear un paquete se utiliza la palabra clave package como primera línea del código fuente package paquete1; La jerarquía de paquetes coincide con la estructura de directorios  package java.awt.imagen;  Carpeta: javaawtimagen Los paquetes se deben organizar de forma lógica
    • La variable de entornoCLASSPATH Sirve para decirle al compilador y al intérprete donde deben buscar las clases que se utilizan en el programa: Set CLASSPATH=.;c:MiJavaMisPaquetes; IMPORTANTE: si no se añade el . (punto) en el classpath, no encuentra las clases aunque estemos dentro del mismo directorio También es necesario definir el classpath para el jdk y alguna variable más: Set CLASSPATH = .;C:j2sdkee1.3.1libj2ee.jar;C:j2sdkee1.3.1libj2eetools.jar; Set JAVA_HOME = C:jdk1.3.1_02 Set J2EE_HOME = C:j2sdkee1.3.1 Set J2EE_CLASSPATH = C:j2sdkee1.3.1libsystemifxjdbc.jar // para Informix Probablemente también sea necesario alguna otra variable para el entorno de desarrollo que estemos utilizando: Set FORTE4J_HOME = C:forte4j // para el entorno Forte de Sun
    • Importar paquetes La palabra clave import nos permite importar clases que residen en otros paquetes import paquete1.*; import paquete1.*; import java.util.Date; import java.util.Date; class MiFecha extends Date { class MiFecha extends Date { // código de la clase // código de la clase }} Esta sentencia no es necesaria, se puede indicar en cada clase a qué paquete pertenece class MiFecha extends java.util.Date { class MiFecha extends java.util.Date { // código de la clase // código de la clase }}
    • Gestión de errores Hay dos clases de error en Java:  Exception: Errores recuperables  Error: Errores graves no recuperables Throwable Exception Error
    • Capturar excepciones Para detectar si se produce una excepción se utiliza la construcción Se puede indicar la clase concreta de excepción que se quiere capturar try { try { // Código que se prueba // Código que se prueba } catch (Exception e) { } catch (Exception e) { // Código si hay excepción // Código si hay excepción }}
    • Orden de los catch Cuando se produce try { try { una excepción, el flujo int a = 5; int a = 5; de programa entra en int b = 0; int b = 0; int c = a/b; el primer catch que }} int c = a/b; capture una clase de catch (ArithmeticException ae){ catch (ArithmeticException ae){ excepción compatible System.out.println( System.out.println( "Error aritmetico); Se deben ordenar los } "Error aritmetico); catch poniendo } catch (Exception e){ catch (Exception e){ primero las System.out.println( System.out.println( excepciones más "Error inesperado: " + "Error inesperado: " + e.getMessage()); específicas } e.getMessage()); }
    • finally Hay operaciones que se quieren realizar tanto si hay error como si todo va bien  Ejemplo: Cerrar una conexión a BD Se utiliza la cláusula finally  El bloque finally siempre se ejecuta try { try { // ... // ... } catch (Exception ex) { } catch (Exception ex) { // Se ejecuta si hay error // Se ejecuta si hay error } finally { } finally { // Siempre se ejecuta // Siempre se ejecuta }}
    • Propagación de excepciones Si una excepción no se captura, se propaga al método anterior en la pila de llamadas Los métodos que pueden producir excepciones contienen la cláusula throws  void metodo(int a) throws IOException {...} Cuando se llama a un método que tiene cláusula throws, existen dos opciones:  Capturar la clase de excepción indicada  Incluir una cláusula throws para la excepción
    • Excepciones propias Se puede crear una clase propia de excepción, construyendo una clase derivada de Exception  Normalmente se sobreescriben los métodos getMessage() y toString()  Por convención, el nombre de una clase de excepción suele terminar con la palabra Exception public class MiException() extends public class MiException() extends Exception{ Exception{ public string getMessage() { public string getMessage() { return "Error propio"; return "Error propio"; }} }} Para lanzar la excepción se utiliza la instrucción throw  throw new MiException();
    • Archivos JAR Las aplicaciones y librerías Java se suelen empaquetar en archivos JAR  Formato ZIP  Contienen toda la estructura de clases (ficheros .class)  Incluyen un fichero de información META-INF/Manifest.mf (fichero de manifiesto)  Pueden incluir ficheros adicionales Los archivos JAR se pueden ejecutar directamente o especificar como rutas de ClassPath
    • Fichero de manifiesto Ejemplo de fichero manifest.mf Manifest-Version: 1.0 Manifest-Version: 1.0 Created-By: 1.5.0-rc (Sun Microsystems Inc.) Created-By: 1.5.0-rc (Sun Microsystems Inc.) Main-Class: paquete.App Main-Class: paquete.App  IMPORTANTE: Terminar todas las líneas con salto de linea  Para aplicaciones ejecutables, el atributo Main- Class indica cual es la clase que contiene el método main (punto de entrada de la aplicación)
    • Tratamiento de archivos JAR Crear archivo JAR: Se utiliza jar.exe  Crear un jar con el contenido del directorio  jar cvf fichero.jar .  Indicar el fichero de manifiesto  jar cvfm fichero.jar MiManifiesto . Ejecutar archivo JAR  java –jar fichero.jar
    • API Java: Fechas
    • Date La clase java.util.Date representa un instante en el tiempo, con precisión de milisegundos  Date d = new Date();  Fecha / hora actual La mayoría de los métodos de esta clase están desaconsejados (deprecated) en favor de las clases Calendar y DateFormat  getTime y setTime convierten la fecha en un número de milisegundos (long)  compareTo permite comparar fechas
    • Calendar (GregorianCalendar) java.util.Calendar es una clase abstracta con métodos para obtener y establecer los valores de una componente de una fecha/hora Los objetos Calendar se crean con una factoría (metodo estático que crea objetos del propio tipo)  Calendar c = Calendar.getInstance();  Devuelve la fecha/hora actual La subclase concreta que se utiliza normalmente es GregorianCalendar En la mayoría de los casos, se puede utilizar Calendar en lugar de Date
    • Componentes de una fecha El método get devuelve un componente de la fecha/hora  int year = c.get(Calendar.YEAR); El método set establece el valor de un componente  c.set(Calendar.DAY_OF_MONTH,15); Componentes de la fecha:  MILLISECOND, SECOND, MINUTE, HOUR, AM_PM, DATE, DAY_OF_MONTH, DAY_OF_WEEK, WEEK_OF_MONTH, WEEK_OF_YEAR, MONTH, YEAR, ERA ATENCIÓN: Los meses van de 0 a 11, no de 1 a 12  Por claridad, es recomendable utilizar las constantes Calendar.JANUARY ... Calendar. DECEMBER getTimeInMillis() devuelve la fecha/hora como un número de milisegundos (como Date.getTime())
    • DateFormat java.text.DateFormat es una clase abstracta que permite convertir valores de fecha a cadena y viceversa Los objetos se crean por medio de una factoría  DateFormat f = DateFormat.getDateInstance();  Para trabajar con fechas  DateFormat f = DateFormat.getTimeInstance();  Para trabajar con horas  DateFormat f = DateFormat.getDateTimeInstance();  Para trabajar con fecha/hora El método parse convierte cadenas a fechas (Date)  Date d = f.parse("31/10/1975"); El método format convierte fechas a cadenas  String s = f.format(d);
    • SimpleDateFormat Para forzar una determinada representación de fecha se puede utilizar la clase derivada SimpleDateFormat El formato de fecha-hora se establece como una cadena de texto  Al crear el objeto  SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");  Con el método applyPattern  f.applyPattern("dd/MM/yyyy hh:mm"); Después se utilizan los métodos estándar de DateFormat para realizar las conversiones
    • API Java: Cadenas
    • String La clase String sirve para almacenar cadenas de texto Unicode Las cadenas de texto son inmutables. No se pueden modificar directamente.  Por eso es seguro realizar asignaciones entre variables String
    • Operaciones con String I Longitud  i = s.length(); Concatenación  s3 = s1 + s2;  s3 = s1.concat(s2); Comparación  b = s1.equals(s2);  b = s1.equalsIgnoreCase(s2);  i = s1.compareTo(s2);  i = s1.compareToIgnoreCase(s2);  b = s1.startsWith(s2);  b = s1.endsWith(s2);
    • Operaciones con String II Obtener carácter  c = s.charAt(0); Obtener subcadena  s2 = s1.substring(i1,i2); Quitar espacios  s2 = s1.trim(); Buscar subcadenas  i = s1.indexOf(s2);  i = s1.lastIndexOf(s2); Reemplazos  s4 = s1.replaceAll(s1,s2);  s4 = s1.replaceFirst(s1,s2);
    • Operaciones con String III Construcción  s = String.format("Nº: %d",i);  s = String.valueOf(i); Conversión mayúsculas/minúsculas  s2 = s1.toLowerCase();  s2 = s1.toUpperCase(); Pasar a matriz de char  char[] c = s.toCharArray(); Dividir en partes  String[] palabras = s.split(" ");
    • Concatenación masiva La operación de concatenación es muy costosa:  1.- Reserva memoria para la cadena final  2.- Copia el contenido de la primera cadena  3.- Copia el contenido de la segunda cadena Si esta operación se repite muchas veces con una misma cadena, el rendimiento se degrada exponencialmente
    • StringBuffer / StringBuilder La clase StringBuffer representa un string modificable.  Se puede modificar su contenido directamente, sin copiar los contenidos  Cuando se queda sin memoria, reserva el doble
    • Métodos StringBuffer I length()  Devuelve la longitud de la cadena contenida setLength()  Establece la longitud  Se rellena con el carácter nulo u0000 capacity()  Devuelve el tamaño reservado ensureCapacity(n)  Reserva al menos la capacidad indicada setCharAt(pos,c)  Modifica el carácter situado en la posición pos
    • Métodos StringBuffer II append(s)  Añade una cadena al final  Sobrecargado para cualquier tipo de datos insert(pos,s)  Inserta una cadena en una posición determinada  Sobrecargado para cualquier tipo de datos delete(pos1,pos2)  Elimina los caracteres desde la posición pos1 a pos2-1 replace(pos1,pos2,s)  Sustituye los caracteres desde la posición pos1 a pos2–1 por la cadena s reverse()  Invierte el orden de los caracteres
    • Práctica String vs StringBuffer Realizar un bucle de 10000 iteraciones que va concatenando un carácter a una cadena  Implementarlo con concatenación de String  Implementarlo con StringBuffer Medir el tiempo que tarda en realizar la operación con cada método Cambiar el número de iteraciones y comprobar el impacto en el rendimiento
    • API Java: Colecciones
    • Java Collections Framework Está basado en una jerarquía de interfaces, pertenecientes al paquete java.util
    • Interfaces de colecciones Collection: Representa un grupo de objetos  Sin implementación directa Set: Colección desordenada que no puede contener duplicados List: Colección ordenada (secuencia) que puede contener duplicados Map: Objeto que almacena pares clave-valor  No puede haber claves duplicadas  Una clave corresponde con un único valor
    • Ordenación de elementos Se pueden construir colecciones ordenadas de elementos  Los elementos implementan la interfaz Comparable  Utilizando un objeto que implemente la interfaz Comparator SortedSet: Set que mantiene sus elementos ordenados con un Comparator SortedMap: Map que mantiene sus elementos ordenados con un Comparator
    • Collection Operaciones básicas  int size()  boolean isEmpty();  boolean contains(Object element);  boolean add(Object element);  boolean remove(Object element);  Iterator iterator(); Operaciones en bloque  boolean containsAll(Collection c);  boolean addAll(Collection c);  boolean removeAll(Collection c);  boolean retainAll(Collection c);  void clear(); Conversión a matriz  Object[] toArray();  Object[] toArray(Object a[]);
    • Iteradores Todas las colecciones se pueden recorrer con un iterador que proporcionan.  hasNext() permite saber si quedan elementos por obtener  next() devuelve el siguiente elemento de la colección  remove() elimina de la colección el último elemento devuelto por next()Collection c = obtenerColeccion(); Collection c = obtenerColeccion();for (Iterator i = c.iterator(); i.hasNext(); ){ for (Iterator i = c.iterator(); i.hasNext(); ){ if (i.next().equals("borrame")) { if (i.next().equals("borrame")) { i.remove(); i.remove(); }}}}
    • Set No añade ningún método específico Impementación: HashSet
    • SortedSet Añade los métodos: SortedSet subSet(Object fromElement, SortedSet subSet(Object fromElement, Object toElement); Object toElement); SortedSet headSet(Object toElement); SortedSet headSet(Object toElement); SortedSet tailSet(Object fromElement); SortedSet tailSet(Object fromElement); Object first(); Object first(); Object last(); Object last(); Comparator comparator(); Comparator comparator(); Impementación: TreeSet
    • List Añade métodos de acceso por posición, búsqueda y rango. Permite utilizar el iterador ListIterator Object get(int index); Object get(int index); Object set(int index, Object element); Object set(int index, Object element); void add(int index, Object element); void add(int index, Object element); Object remove(int index); Object remove(int index); boolean addAll(int index, Collection c); boolean addAll(int index, Collection c); int indexOf(Object o); int indexOf(Object o); int lastIndexOf(Object o); int lastIndexOf(Object o); ListIterator listIterator(); ListIterator listIterator(); ListIterator listIterator(int index); ListIterator listIterator(int index); List subList(int from, int to); List subList(int from, int to); Impementaciones: ArrayList, LinkedList
    • ListIterator Permite ir hacia delante y hacia atrás, insertar y modificar elementos boolean hasNext(); boolean hasNext(); Object next(); Object next(); boolean hasPrevious(); boolean hasPrevious(); Object previous(); Object previous(); int nextIndex(); int nextIndex(); int previousIndex(); int previousIndex(); void remove(); void remove(); void set(Object o); void set(Object o); void add(Object o); void add(Object o);
    • Map Trabaja con pares clave-valor Operaciones básicasObject put( Object put( Object key, Object key, Object value) Object value)Object get(Object key) Object get(Object key)Object remove(Object key) Object remove(Object key)boolean containsKey( boolean containsKey( Object key); Object key);boolean containsValue( boolean containsValue( Object value); Object value);int size(); int size();boolean isEmpty(); boolean isEmpty();
    • Map Operaciones en bloque void putAll(Map t); void putAll(Map t); void clear(); void clear(); Obtener colecciones asociadas public Set keySet(); public Set keySet(); public Collection values(); public Collection values(); public Set entrySet(); public Set entrySet(); public interface Entry { public interface Entry { Object getKey(); Object getKey(); Object getValue(); Object getValue(); Object setValue(Object v); Object setValue(Object v); }} Implementación: HashMap
    • SortedMap Añade los métodos: Comparator comparator(); Comparator comparator(); SortedMap subMap(Object fromKey, SortedMap subMap(Object fromKey, Object toKey); Object toKey); SortedMap headMap(Object toKey); SortedMap headMap(Object toKey); SortedMap tailMap(Object fromKey); SortedMap tailMap(Object fromKey); Object firstKey(); Object firstKey(); Object lastKey(); Object lastKey(); Implementación: TreeMap
    • Collections La clase Collections proporciona métodos estáticos para realizar operaciones sobre colecciones sort(List l) sort(List l) sort(List l, Comparator c) sort(List l, Comparator c) shuffle(List l) shuffle(List l) shuffle(List l, Random r) shuffle(List l, Random r) binarySearch(List l, Object o) binarySearch(List l, Object o) binarySearch(List l, Object o, Comparator c) binarySearch(List l, Object o, Comparator c) reverse(List l) reverse(List l) fill(List l, Object o) fill(List l, Object o) copy(List dest, List orig) copy(List dest, List orig) max(Collection c) max(Collection c) max(Collection c, Comparator cmp) max(Collection c, Comparator cmp) min(Collection c) min(Collection c) min(Collection c, Comparator cmp) min(Collection c, Comparator cmp)
    • Práctica: Agenda de teléfonos Aplicación de consola que  La aplicación debe implemente una agenda de permitir consultar, teléfonos añadir, modificar y Cada registro de la agenda eliminar registros de la debe contener:  Nombre corto agenda  Nombre completo  Opciones de menú:  Dirección  Listado de agenda  Teléfono  Consultar registro  E-mail  Modificar registro Se accede a los registros  Añadir registro por el nombre corto  Eliminar registro  Salir
    • Novedades JDK 1.5 Tipos genéricos:  Todas las colecciones se pueden parametrizar con el tipo de elemento que contienen List<String> lista = new ArrayList<String>(); lista.add("Hola"); Bucle for para iteradores  Se añade una sintaxis alternativa para el bucle for que permite recorrer de manera sencilla colecciones y matrices for (String s : lista) { System.out.println(s); }
    • Tratamiento de ficheros
    • Clase File Sirve para manejar directorios y ficheros  Renombrar / Mover  Borrar  Crear directorios  Listar ficheros  Acceder a propiedades  Fecha modificación, tipo de archivo,…
    • Métodos de FileString getName() String getName()String getParent() String getParent()long length() long length()boolean renameTo(File dest) boolean renameTo(File dest)boolean delete() boolean delete()boolean canRead() / boolean canWrite() boolean canRead() / boolean canWrite()boolean exists() boolean exists()boolean mkdir() boolean mkdir()File[] list() / File[] listFiles() File[] list() / File[] listFiles()long lastModified() / void setLastModified(long long lastModified() / void setLastModified(longt) t)boolean isDirectory() boolean isDirectory()boolean isFile() boolean isFile()boolean createNewFile() boolean createNewFile()
    • EjemploFile f1 = new File(“C:prueba.txt”); File f1 = new File(“C:prueba.txt”);if (f1.exists()) { if (f1.exists()) { f1.delete(); f1.delete();}}else { else { f1.createNewFile(); f1.createNewFile();}}File dir = new File(“C:”); File dir = new File(“C:”);File[] ficheros = dir.listFiles(); File[] ficheros = dir.listFiles();for (int i=0; i<ficheros.length; i++) { for (int i=0; i<ficheros.length; i++) {System.out.println(ficheros[i].getName()); System.out.println(ficheros[i].getName());}}
    • Flujos de datos Paquete java.io Tenemos flujos de datos de una fuente a un receptor Java soporta dos tipos de datos en los flujos:  Bytes  Caracteres Unicode Stream: cualquier tipo de secuencia de bytes que pueda ser leída o escrita  InputStream, OutputStream Reader: objeto para leer caracteres Unicode Writer: objeto para escribir caracteres Unicode
    • InputStream Ofrece los siguientes métodos//lectura //lecturaint read() int read()int read(byte[] int read(byte[] buffer) buffer)int read(byte[] int read(byte[] buffer, int offset, int length) buffer, int offset, int length)//cerrar flujo //cerrar flujovoid close() void close()//cantidad bytes disponibles //cantidad bytes disponiblesint available() int available()//descarta la cantidad de bytes especificada //descarta la cantidad de bytes especificadalong skip(long n) long skip(long n)
    • OutputStream  Ofrece los siguientes métodos//escritura //escrituravoid write() void write()void write(byte[] void write(byte[] buffer) buffer)void write(byte[] void write(byte[] buffer, int offset, int length) buffer, int offset, int length)//cerrar flujo //cerrar flujovoid close() void close()//fuerza la grabación en la salida //fuerza la grabación en la salidavoid flush() void flush()
    • Reader Ofrece los siguientes métodos//lectura //lecturaint read() int read()int read(char[] int read(char[] cbuf) cbuf)int read(char[] int read(char[] cbuf, int offset, int length) cbuf, int offset, int length)//cerrar flujo //cerrar flujovoid close() void close()//si está disponible para leer //si está disponible para leerboolean ready() boolean ready()//descarta la cantidad de caracteres especificada //descarta la cantidad de caracteres especificadalong skip(long n) long skip(long n)
    • Writer Ofrece los siguientes métodos//escritura //escrituravoid write() void write()void write(char[] void write(char[] cbuf) cbuf)void write(char[] void write(char[] cbuf,int offset, int length) cbuf,int offset, int length)void write(String void write(String string) string)Void write(String Void write(String string,int offset, int length) string,int offset, int length)//cerrar flujo //cerrar flujovoid close() void close()//fuerza la grabación en la salida //fuerza la grabación en la salidavoid flush() void flush()
    • Flujos directos Tipo Flujos de caracteres Flujos de byteFichero FileReader FileInputStream FileWriter FileOutputStreamMemoria CharArrayReader ByteArrayInputStream(Array) CharArrayWriter ByteArrayOutnputStreamMemoria StringReader N/A(String) StringWriterPipe PipeReader PipeInputStream PipeWriter PipeOutputStream
    • Flujos de procesamiento Realizan conversiones a otro flujo También se les llama flujos de filtro Un flujo de entrada de filtro se crea con una conexión a un flujo de entrada existente Cuando leemos de él, accedemos a caracteres de otro flujo de entrada Se usan para convertir una secuencia de datos más usable para la aplicación que está escribiendo
    • Lista de flujos de procesamiento Tipo Flujo de Flujo de Bytes caracteresBuffering BufferedReader BufferedInputStream(mejora rendimiento) BufferedWriter BufferedOutputStreamFiltrado FilterReader FilterInputStream(clases abstractas) FilterWriter FilterOutputStreamConversión de bytes a InputStreamReadercaracteres OutputStreamReaderSerialización de objetos ObjectInputStream ObjectOutputStreamSerialización de datos primitivos DataInputStream DataOutputStreamSoporte números de línea LineNumberReader LineNumberInputStreamFormateo de datos primitivos PrintWriter PrintStreamOtros (no pertenecen a java.io): CipherInputStreamCifrado / descifrado CipherOutputStreamComprimir / descomprimir InflaterInputStream
    • Cadenas de flujos  Un programa suele encadenar una serie de flujos para procesar los datos  Encadenamiento flujos de entradaData Source Program FileInputStream BufferedInputStream DataInputStream  Encadenamiento flujos de salida Program Data Sink FileOutputStream DataOutputStream BufferedOutputStream
    • Ejemplo//defino los flujos de entrada y salida //defino los flujos de entrada y salidaFileReader input = new FileReader(args[0]); FileReader input = new FileReader(args[0]);FileWriter output = new FileWriter(args[1]); FileWriter output = new FileWriter(args[1]);char[] buffer = new char[128]; char[] buffer = new char[128];int charsRead; int charsRead;//leemos el primer buffer //leemos el primer buffercharsRead = input.Read(buffer); charsRead = input.Read(buffer);while(charsRead != -1){ while(charsRead != -1){ output.write(buffer,0,charsRead); output.write(buffer,0,charsRead); charsRead = input.Read(buffer); charsRead = input.Read(buffer);}}input.close(); input.close();output.close(); output.close();
    • Clase BufferedReader Maneja el proceso de buffering  Optimiza el rendimiento Permite leer un flujo de texto línea a línea  readLine() Es un flujo de procesamiento
    • Ejemplo 2FileReader input = new FileReader(args[0]); FileReader input = new FileReader(args[0]);BufferedReader bufInput = new BufferedReader(input); BufferedReader bufInput = new BufferedReader(input);FileWriter output = new FileWriter(args[1]); FileWriter output = new FileWriter(args[1]);BufferedWriter bufOutput = new BufferedWriter(output); BufferedWriter bufOutput = new BufferedWriter(output);String line; String line;//leemos la primera línea //leemos la primera línealine = bufInput.readLine(); line = bufInput.readLine();while(line != null){ while(line != null){ bufOutput.write(line,0,line.length()); bufOutput.write(line,0,line.length()); bufOutput.newLine(); bufOutput.newLine(); line = bufInput.readLine(); line = bufInput.readLine();}}bufInput.close(); bufInput.close();bufOutput.close(); bufOutput.close();
    • Jerarquía clase InputStream FileInputStream ObjectInputStream PipedInputStream DataInputStreamInputStream SequenceInputStream PushbackInputStream FilterInputStream BufferedInputStream StringBufferInputStream LineNumberInputStream ByteArrayInputStream
    • Jerarquía clase OutputStream FileOutputStream DataOutputStream ObjectOutputStream PushbackOutputStreamOutputStream FilterOutputStream BufferedOutputStream LineNumberOutputStream PipedOutputStream ByteArrayOutputStream
    • FileInputStream / FileOutputStream  Podemos especificar la ruta del fichero del que queremos leer o escribir  FileInputStream: si el fichero no existe, da error  FileOutputStream: si el fichero existe, se sobrescribeFileInputStream infile = new FileInputStream(“read.dat”); FileInputStream infile = new FileInputStream(“read.dat”);FileOutputStream outfile = new FileOutputStream outfile = newFileOutputStream(“write.dat”); FileOutputStream(“write.dat”);
    • Jerarquía clase Reader BufferedReader LineNumberReader PipedReader InputStreamReader FileReaderReader FilterReader PushbackReader StringReader CharArrayReader
    • Jerarquía clase Writer BufferedWriter StringWriter OutputStreamWriter FileWriterWriter FilterWriter PipedWriter PrintWriter CharArrayWriter
    • InputSteamReader / OutputStreamReader  Podemos especificar la codificación de caracteres que vamos a leer, si es diferente a la localInputStreamReader ir = new InputStreamReader(System.in, “ISO-8859-1”); InputStreamReader ir = new InputStreamReader(System.in, “ISO-8859-1”);  ISO 8859-1 corresponde con ASCII + caracteres occidentales (acentos, ñ,...)
    • FileReader / FileWriter Son análogas a encadenar:  InputStreamReader sobre FileInputStream  OutputStreamWriter sobre FileOutputStream Utilizan codificación de caracteres por defecto
    • Redes
    • Sockets Son los puntos finales de una comunicación entre procesos Para comunicarse por red, Java utiliza el modelo de flujos Un socket puede tener asociados dos flujos, uno de entrada y otro de salida Las conexiones socket TCP/IP están implementadas en el paquete java.net
    • Configurar la conexión Una máquina debe ejecutar un programa que esté esperando una conexión y otra debe intentar acceder a la primera Debemos proporcionar la dirección a la que conectarnos y el puerto  Los puertos van del 0 al 65535  Inferiores al 1024 están reservados Para establecer la conexión las dos máquinas deben acordar el mismo puerto
    • Modelo de conexiones ServidorServerSocket(puerto #)ServerSocket.accept() Cliente Socket(host,puerto #) Socket() (intenta conectarse) OutputStream OutputStream InputStream InputStream Socket.close() Socket.close()
    • Ejemplo Servidor TCP/IPServerSocket s = new ServerSocket(5432); ServerSocket s = new ServerSocket(5432);while (true){ while (true){ Socket s1 = s.accept(); Socket s1 = s.accept(); OutputStream s1out = s1.getOutputStream(); OutputStream s1out = s1.getOutputStream(); BufferedWriter bw = new BufferedWriter(new BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s1out)); OutputStreamWriter(s1out)); bw.write(“Hola”); bw.write(“Hola”); bw.close(); bw.close(); s1.close(); s1.close();}}
    • Ejemplo cliente TCP/IPSocket s1 = new Socket(“127.0.0.1”,5432); Socket s1 = new Socket(“127.0.0.1”,5432);InputStream is = s1.getInputStream(); InputStream is = s1.getInputStream();DataInputStream dis = new DataInputStream(is); DataInputStream dis = new DataInputStream(is);System.out.println(dis.readUTF()); System.out.println(dis.readUTF());dis.close(); dis.close();s1.close(); s1.close();
    • Programación multihilo
    • Hilos Paquete java.lang.Thread Un proceso es un programa en ejecución Uno o más hilos constituyen un proceso Un hilo está compuesto por:  Una CPU virtual  El código que ejecuta la CPU  Los datos sobre los que trabaja el código
    • Creación de un hilo I Necesitamos una clase que implemente el interfaz Runnable class HolaRunner implements Runnable{ class HolaRunner implements Runnable{ int i; int i; public void run(){ public void run(){ i = 0; i = 0; while(true) { while(true) { System.out.println(“Hola “ + i); System.out.println(“Hola “ + i); if (i==50) { if (i==50) { break; break; }} }} }} }}
    • Creación de un hilo II Ahora creamos un objeto de la clase Thread pasando como argumento una instancia de la clase HolaRunner HolaRunner HolaRunner r = r = new HolaRunner(); new HolaRunner(); Thread t = Thread t = new new Thread(r); Thread(r); t.start(); t.start(); Un hilo siempre comienza su ejecución en el método run de su instancia Runnable cargada (r)
    • Multihilos Podemos crear tantos hilos como queramos Thread t1 = new Thread(r); Thread t1 = new Thread(r); Thread t2 = new Thread(r); Thread t2 = new Thread(r); Estos hilos comparten los mismos datos y el mismo código Hasta que no ejecutamos el método start el hilo no comienza
    • Planificación de hilos Un hilo puede estar en varios estados:  Runnable  Running  Blocked Se puede llamar al método sleep para parar el hilo  Thread.sleep(10); // Milisegundos  Pasaría a blocked
    • Finalización de un hilo Cuando un hilo completa su ejecución no puede ejecutarse nuevamente Si queremos, también podemos pararlo antes de que acabe  Haremos que finalice el método Run
    • Métodosboolean isAlive() boolean isAlive()void setPriority() void setPriority() Thread.MIN_PRIORITY Thread.MIN_PRIORITY Thread.NORM_PRIORITY Thread.NORM_PRIORITY Thread.MAX_PRIORITY Thread.MAX_PRIORITYvoid void join() join()void void join(long timeout) join(long timeout)Thread.sleep() Thread.sleep()Thread.yield() Thread.yield()
    • Otra forma de crear hilos La clase Thread implementa el interfaz Runnable, por lo tanto se puede crear un hilo creando una clase que extienda de Thread public class MyThread extends Thread{ public class MyThread extends Thread{ public void run() { public void run() { ... ... }} }} ... ... public static void main(String args[]) public static void main(String args[]) {{ Thread t = new MyThread(); Thread t = new MyThread(); t.start(); t.start(); }}
    • Palabra clave synchronized Podemos tener problemas si varios hilos acceden a los mismos datos Necesitamos asegurarnos de que los datos están en estado consistente antes de comenzar otro hilo Al usar synchronized, comprobamos el estado del objeto  Obtenemos la bandera de bloqueo asociada al objeto
    • Ejemplo synchronized public class Probando{ public class Probando{ public void prueba(char c){ public void prueba(char c){ synchronized(this) { synchronized(this) { datos[i] = c; datos[i] = c; i++; i++; }} }} }} Al ejecutar la orden synchronized, intenta obtener la bandera de bloqueo Si no la consigue, el hilo para su ejecución hasta que la consiga
    • Uso synchronized Sólo funciona si todos los accesos a los datos ocurren dentro de bloques sincronizados Estospublic void deben declarar private datos se push(char c){ public void push(char c){ synchronized(this){ synchronized(this){ //código //código }} }} óó public synchronized push(char c){ public synchronized push(char c){ //código //código }}
    • Bloqueo mutuo (Deadlock) Ocurre cuando un hilo espera un bloqueo que tiene otro y ese otro espera un bloqueo que tiene el primero Para prevenirlo, hay que establecer un orden en los bloqueos para obtenerlos y liberarlos en orden inverso
    • Métodos wait y notify Son métodos para comunicación entre hilos wait: un hilo envía esta llamada, queda pausado y libera el bloqueo notify: otro hilo notifica a un hilo pausado que continúe  El hilo despertado podrá obtener el bloqueo nuevamente cuando se libere y continuará con la siguiente instrucción tras el wait Para hacer estas llamadas tenemos que tener un bloqueo sobre el objeto  Tienen que estar dentro de un bloque synchronized
    • Acceso a datos JDBC
    • Acceso a datos JDBC 1.2  Tipos de drivers  Carga de los Drivers  Establecimiento de conexiones a BB.DD.  Statements de JDBC.  Manipulación del conjunto de resultados  Mapeo de tipos entre SQL y Java  Transacciones. JDBC 2.0 JDBC 3.0
    • JDBC 1.2 Interfaces  Clases  CallableStatement  Date  Connection  DriverManager  DatabaseMetaData  DriverPropertyInfo  Driver  Time  PreparedStatement  TimeStamp  ResultSet  Types  ResultSetMetaData  Excepciones  Statement  DataTruncation  SQLException  SQLWarning
    • Relación entre clases executeQuery ResultSet getMoreResults Statement commit, abort execute createStatement getXXX Prepared prepareStatement Connection Statement setXXX prepareCallTipos de Datos Date, Time, getXXX CallableStatement getConnection TimeStamp, Numeric, etc. DriverManager
    • Drivers JDBC Un driver JDBC es un módulo Java que traduce los métodos estándar JDBC en llamadas a la base de datos de destino Hay cuatro tipos de drivers distintos:  Tipo 1 : Puente JDBC-ODBC  Tipo 2 : API Nativo  Tipo 3: Protocolo de red abierto (puro Java)  Tipo 4: Protocolo de red propietario (puro Java)
    • Driver tipo 1: Puente JDBC - ODBC sun.jdbc.odbc.JdbcOdbcDriver Oracle Oracle ODBC Driver Cliente de API ODBC BBDD Java JDBC Manager SQLServer SQLServer SQLServer ODBC Driver Muy dependiente de la plataforma Windows Requiere instalación en la máquina cliente Demasiadas capas: Impacto en la eficiencia Access No apto para entornos de producción ni de aplicaciones comerciales. MS Access ODBC Driver
    • Driver tipo 2: API nativa Protocolo específico del vendedor (SQL*Net, DB2, étc)Cliente de API Controlador del Tipo2BBDD Java JDBC (código binario y Java) BBDD Implementado como una combinación de código nativo y Java Muy dependiente de la plataforma Requiere instalación en la máquina cliente
    • Driver tipo 3: Protocolo de red abierto Cliente de API Controlador JDBC BBDD Java JDBC Tipo 3 (Java Puro) Protocolo de Comunicaciones estándar (HTTP) IDS Server Servidor Remoto (Intermediario) de Acceso a Base de Datos Integramente en Java Sin instalación Oracle SQLServer Access Aplicaciones inter/intranet
    • Driver tipo 4: Protocolo de red propietario oracle.jdbc.driver.OracleDriver Cliente de API Controlador JDBC BBDD Java JDBC Tipo 4 (Java Puro) Oracle Protocolo de Red propietario: SQL*Net jdbc:oracle:thin:[<user>/<password>]@<host>:<port>:<sid> Integramente en Java Sin instalación Aplicaciones inter/intranet
    • Crear una conexión La clase DriverManager es la responsable de cargar y descargar los controladores JDBC y crear conexiones  Deduce el driver que se debe utilizar a partir de la URL de conexión Para que DriverManager sea capaz de utilizar un determinado driver JDBC, hay que cargarlo en memoria previamente
    • URL de conexión El formato de la URL de conexión depende del driver  Siempre comienza con jdbc:driver: ODBC: sun.jdbc.odbc.JdbcOdbcDriver  jdbc:odbc:NombreDSN SQL Server: com.microsoft.jdbc.sqlserver.SQLServerDriver  jdbc:microsoft:sqlserver://localhost:1433; DatabaseName=Northwind;SelectMethod=cursor; Oracle: oracle.jdbc.driver.OracleDriver  jdbc:oracle:thin:@localhost:1521:orcl MySQL: com.mysql.jdbc.Driver  jdbc:mysql://localhost:3306/test
    • Ejemplo: Crear conexióntry { try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");} catch (ClassNotFoundException e) { } catch (ClassNotFoundException e) { // mensaje de error} // mensaje de error}}}Connection con = DriverManager.getConnection( Connection con = DriverManager.getConnection( "jdbc:odbc:myDataSource", "admin", "pwd"); "jdbc:odbc:myDataSource", "admin", "pwd");
    • Metadatos DatabaseMetaData  Se obtiene de la conexión  Devuelve información acerca de la estructura de la base de datos  DatabaseMetadata dmd = con.getMetaData();  ResultSet tablas = dmd.getTables(……); ResultSetMetaData  Se obtiene de un objeto ResultSet  Devuelve información sobre las columnas que forman el ResultSet  ResultSet rs = stmt.executeQuery(sqlString);  ResultSetMetaData rsmd = rs.getMetaData();  int colType[] = new int[rsmd.getColumnCount()];
    • Statement Para ejecutar consultas o modificaciones sobre la BD, hay que crear antes un objeto Statement  Se utiliza el método createStatement() de la conexión Una instancia de Statement se puede reutilizar para realizar varias operaciones Para realizar una consulta, se utiliza el método executeQuery(sentenciaSQL)  Devuelve un objeto ResultSet  Si se obtienen varios conjuntos de datos, se puede pasar al siguiente con getMoreResults() Para realizar una modificación (o cualquier operación que no devuelva datos), se utiliza el método executeUpdate(sentenciaSQL)  Devuelve el número de filas afectadas
    • Ejemplo: StatementStatement st = con.createStatement(); Statement st = con.createStatement();ResultSet rs = st.executeQuery( ResultSet rs = st.executeQuery( "SELECT * FROM PRODUCTS"); "SELECT * FROM PRODUCTS");st.executeUpdate( st.executeUpdate( "UPDATE PRODUCTS SET NAME=CocaCola " "UPDATE PRODUCTS SET NAME=CocaCola " + "WHERE PRODUCTID=1"); + "WHERE PRODUCTID=1");
    • Método execute El método execute(sql) permite ejecutar un Statement cuando no se sabe si contiene una consulta o una sentencia de actualización  Devuelve true si es una consulta  Devuelve false si es una actualización El método getResultSet() devuelve el conjunto de resultados obtenido  Si no es una consulta, devuelve null El método getUpdateCount() devuelve el número de registros actualizados
    • ResultSet El resultado de una consulta es un objeto ResultSet  next() permite pasar a la siguiente fila  devuelve true si ha podido leer la fila  getInt(..), getString(..), etc. devuelven el valor de una columna  Se pueden obtener por posición o por nombre (las posiciones empiezan en 1)  rs.getInt(1) o rs.getInt("ID")  close() cierra el ResultSet El ResultSet de JDBC 1.2 sólo permite avanzar por las filas hacia delante y leer las columnas de izquierda a derecha una sola vez
    • Ejemplo: ResultSetStatement st = con.createStatement();Statement st = con.createStatement();ResultSet rs = st.executeQuery(ResultSet rs = st.executeQuery( "SELECT * FROM PRODUCTS"); "SELECT * FROM PRODUCTS");while (rs.next()) {while (rs.next()) { System.out.print("ID: "); System.out.print("ID: "); System.out.println(rs.getInt(0)); System.out.println(rs.getInt(0)); System.out.print("Nombre: "); System.out.print("Nombre: "); System.out.println(rs.getString(1)); System.out.println(rs.getString(1)); System.out.println(); System.out.println();}}rs.close();rs.close();
    • JOINS No todos los gestores de BD realizan igual las combinaciones de tablas (joins) JDBC proporciona una sintaxis especial que el driver se encarga de traducir  SELECT d.name AS Departamento, e.* FROM {oj dept d left outer join emp e on d.deptno=e.deptno}
    • PreparedStatement Si se va a lanzar la misma operación varias veces con distintos parámetros se puede optimizar utilizando PreparedStatement (deriva de Statement)  La sentencia se precompila y es más eficiente Los objetos PreparedStatement se crean con el método prepareStatement(sql) de la conexión Los parámetros se indican en la SQL con ? Los valores de los parámetros se establecen con los métodos setInt, setString, etc.  Reciben la posición del parámetro y el valor que toma  La posición empieza en 1
    • Ejemplo: PreparedStatementPreparedStatement ps =PreparedStatement ps = con.prepareStatement( con.prepareStatement( "SELECT * from Autor " + "SELECT * from Autor " + "WHERE ID=?"); "WHERE ID=?");ps.setInt(1,1);ps.setInt(1,1);ResultSet rs = ps.executeQuery();ResultSet rs = ps.executeQuery();
    • CallableStatement Se utiliza para llamar a procedimientos almacenados Se crean con el método prepareCall(sql) La SQL tiene la estructura: "{call nombre_proc(?,?)}" Parámetros  Entrada: como en PreparedStatement  Salida: se deben registrar antes de la ejecución con el método registerOutParameter(pos,tipo) Se ejecuta llamando al método execute() El resultado se obtiene llamando al método getResultSet()
    • Ejemplo: PreparedStatementCallableStatement cs = con.prepareCall( CallableStatement cs = con.prepareCall( "{call InsertarEmpleado(?,?,?)}"); "{call InsertarEmpleado(?,?,?)}");String nombre = "José García"; String nombre = "José García";int edad = 43 int edad = 43cs.setString(1,nombre); cs.setString(1,nombre);cs.setInt(2,edad); cs.setInt(2,edad);cs.registerOutParameter(3,java.sql.Types.INTEGER); cs.registerOutParameter(3,java.sql.Types.INTEGER);ResultSet rs = ps.executeQuery(); ResultSet rs = ps.executeQuery();while (rs.next()) { while (rs.next()) { System.out.println("Insertado empleado: " + System.out.println("Insertado empleado: " + rs.getString(1) + " - " + rs.getString(2)); rs.getString(1) + " - " + rs.getString(2));}}int id = cs.getInt(3); int id = cs.getInt(3);
    • Transacciones Por defecto, las conexiones funcionan en modo autocommit  Cada operación conlleva su propia transacción Si se deshabilita autocommit (setAutoCommit(false)), las transacciones se controlan manualmente  Se inician al ejecutar cualquier Statement  commit() acepta la transacción  rollback() descarta la transacción
    • Concurrencia detransacciones Cuando se ejecutan a la vez distintas transacciones se pueden presentar los siguientes problemas  Lecturas sucias: Se leen datos insertados por otras transacciones que aún no se han confirmado  Lecturas no repetibles: Se lee la misma fila dos veces seguidas y se obtienen datos distintos (modificaciones de otras transacciones)  Lecturas fantasma: Se leen varias filas que cumplen cierto criterio dos veces seguidas y se obtienen filas distintas (inserciones o borrados de otras transacciones)
    • Niveles de aislamiento Se especifican en el método setTransactionIsolation(...) Connection.TRANSACTION_NONE  No utiliza transacciones Connection.TRANSACTION_READ_UNCOMMITED  Permite lecturas sucias, no repetibles y fantasma Connection.TRANSACTION_READ_COMMITED  Permite lecturas no repetibles y lecturas fantasma Connection.TRANSACTION_REPEATABLE_READ  Permite sólo lecturas fantasma Connection.TRANSACTION_SERIALIZABLE  Se asegura la consistencia de todas las lecturas
    • JDBC 2.0 Mejoras en ResultSet  ResultSet desplazables  ResultSet actualizables Actualizaciones en lote Tipos de datos avanzados Optimización de conexiones (pooling) Uso de JNDI (Java Naming and Directory Interface) para localizar bases de datos Conjuntos de datos con soporte JavaBean (RowSet) Transacciones distribuidas (JTS: Java Transaction Services)
    • Mejoras en ResultSet createStatement(SCROLLTYPE,UPDATETYPE)  SCROLLTYPE  Resultset.TYPE_FORWARD_ONLY  Desplazamiento sólo hacia adelante  Resultset.TYPE_SCROLL_INSENSITIVE  Permite desplazamiento, pero no ve cambios realizados por otros  Resultset.TYPE_SCROLL_SENSITIVE  Permite desplazamiento y ve los cambios  UPDATETYPE  Resultset.CONCUR_READ_ONLY:  Sólo lectura  Resultset.CONCUR_UPDATABLE  Permite modificar los datos
    • Desplazamiento por ResultSet void afterlast();  boolean last();  Se desplaza a la posición siguiente de la última fila  Se posiciona en la última fila boolean isAfterLast();  boolean isLast();  Indica si está posicionado  Indica si está en la última fila después de la última fila void beforefirst();  boolean next();  Se desplaza a la posición anterior  Se mueve a la siguiente fila a la primera fila  boolean previous(); boolean isBeforeFirst();  Se mueve a la fila anterior  Indica si está posicionado antes de la primera fila  boolean relative(int n); boolean first();  Se mueve n filas desde la fila  Se posiciona en la primera fila actual boolean isFirst();  boolean absolute(int n);  Indica si está en la primera fila  Se posiciona en la fila nº n
    • ResultSet actualizables Actualización de filas  Los métodos updateInt(col,valor), updateString(col,valor), etc. modifican una columna de la fila actual con el valor indicado  El método updateRow() almacena los cambios en la BD  Si se desplaza el ResultSet antes de llamar a updateRow() se pierden los cambios  El método cancelRowUpdates() restaura los valores originales de la fila
    • ResultSet actualizables Inserción de filas  Desplazarse a la "fila de inserción" con el método moveToInsertRow()  Introducir los datos con los métodos updateXXX()  Guardar la fila con insertRow() Borrado de filas  Se utiliza el método deleteRow()
    • Actualizaciones en lote Se deshabilita autocommit  con.setAutoCommit(false); Se contruye un Statement  Statement st = con.createStatement (); Se añaden sentencias al Statement  st.addBatch("...") Se envían las sentencias a la BD  int[] rowCounts = st.updateBatch();  Devuelve un array con el número de filas afectadas por cada sentencia del lote
    • Tipos de datos avanzados DISTINCT STRUCT ARRAY BLOB CLOB REF
    • JDBC 3.0 SavePoints (transacciones parciales) Pool de PreparedStatement Recuperación de claves autogeneradas Soporte de cursor Hold Posibilidad de mantener varios ResultSet abiertos a la vez
    • SavePoints Permite deshacer parcialmente una transacción: Statement stmt = con.createStatement(); Statement stmt = con.createStatement(); stmt.executeUpdate( stmt.executeUpdate( "INSERT INTO TAB1(COL1) VALUES "INSERT INTO TAB1(COL1) VALUES (PRIMERO)"); (PRIMERO)"); Savepoint svpt1 = Savepoint svpt1 = con.setSavepoint("SAVEPOINT_1"); con.setSavepoint("SAVEPOINT_1"); stmt.executeUpdate( stmt.executeUpdate( "INSERT INTO TAB1 (COL1) VALUES "INSERT INTO TAB1 (COL1) VALUES (SEGUNDO)"); (SEGUNDO)"); con.rollback(svpt1); con.rollback(svpt1);
    • Obtener claves generadas Indicar en executeUpdate el parámetro Statement.RETURN_GENERATED_KEYS Ejecutar getGeneratedKeys() para obtener un ResultSet con las claves generadas Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement(); stmt.executeUpdate( stmt.executeUpdate( "INSERT INTO ORDERS (...) VALUES (...)", "INSERT INTO ORDERS (...) VALUES (...)", Statement.RETURN_GENERATED_KEYS ); Statement.RETURN_GENERATED_KEYS ); ResultSet rs = stmt.getGeneratedKeys(); ResultSet rs = stmt.getGeneratedKeys(); if (rs.next()) { if (rs.next()) { int clave = rs.getInt(1); int clave = rs.getInt(1); }}
    • Enlaces y Bibliografía En Internet:  http://java.sun.com Página oficial de Sun (inglés)  Documentación API J2SE http://java.sun.com/j2se/1.5.0/docs/api/index.html Libros:  "Piensa en Java" Bruce Eckel - Pearson Educación