====== Java ====== * [[highlevel:java:guis|Programación de interfaces gráficas]] * [[highlevel:java:2d|Programación gráfica 2d]] * [[highlevel:java:xtra|Tips del lenguaje]] ===== Sintaxis básica ===== * Definición del main: **public static void main (String[] args)** * La clase System está en el paquete java.lang, y este se implementa por defecto. * Los includes (o usings) de java se llaman imports, puedes importar una clase en concreto: import java.util.Date; o todo un paquete: import java.util.*; * Variables base: //byte, short, int, long, float, double, char y boolean//. * Conversiones forzadas (o casts): **byte b = (byte)var;** ==== Declaración de variables ==== int i; int i = 3; int i = 3, j = 4; int k = i + j; ==== Arrays ==== double cuentas[] = new double [2]; // cuentas[0] double cuentas[] = {0.1, 34.3}; // cuentas[0] double cuentas[][] = new double[2][100]; // cuentas[0][0] double cuentas[]; double cuentas[][] = {{3.0, 2.3}, {34.3, 1}}; // cuenta[0][0] Los arrays multidimensionales son arrays de arrays, por lo que podemos acceder de forma a sus arrays internos: double array[][] = new double[2][]; array[0] = new double[30]; array[1] = new double[54]; Tienen una propiedad //length//. ==== Valores numéricos ==== * Creación de ints mediante otros formatos : int value; value = 16; // decimal value = 020; // octal value = 0x10; // hexadecimal * Valores con coma: float var = 0.5f; double var = 0.5d; // o double var = 0.5; Ya que por defecto son doubles. ==== Carácteres ==== * Podemos asignar valores numéricos a los chars, entonces estos tomarán su carácter correspondiente de la tabla unicode. * Podemos cojer un carácter de un String con el método **charAt(int)** * Podemos saber si un carácter es un número o una letra con los métodos **Character.isDigit** o **Character.isLetter**. ==== Operadores ==== -- decremento - resta ! no lógico != distinto % módulo %= asignación del módulo & AND a nivel de bit && AND lógico &= asignación del AND * multipicación *= asignación de la multiplicación / división /= asignación de la división ?: if-then-else ^ Xor a nivel de bit ^= asignación de Xor |= asignación de OR += asignación de suma <<= asignación de desplazamiento a la izquierda <= menor o igual que -= asignación de resta >>= asignación de desplazamiento a la derecha >>>= asignación de desplazamiento a la derecha con relleno de ceros ==== Sentencias ==== * Switch: switch (byte/char/short/int) { case valor: break; default: } * For: for (int i=0, iDoble =0; i<=10; i++, iDoble = i * 2); for (int i=0; i < array.length; sum += arra[i++]); for (; temp > 0; ); <- Se convierte en un while * Se puede usar la sentencia "break" para romper la continuidad de un bucle. * Se puede usar la sentencia "continue" para saltar una iteracción de un bucle. for (int i=0; i<10; i++) { if (i==0) continue; ... } ==== Strings ==== * Podemos usar su constructor para pasar de //byte[]// a string. * Contiene métodos cucos como el //charAt, compareTo, concat// (aunque podemos ussar el signo +), //compareToIgnoreCase, endsWith, getBytes// (para convertirlo a byte[]), //length, replace, startsWith, substring, CharArray, toLowerCase, toUpperCase, trim...// * Para convertir una cadena a int usaremos la clase //Integer.ParseInt//. * Para convertir una cadena a double usaremos el constructor de los Doubles: //double d = new Double(str);// * Para convertir de cualquier tipo base (//int, double//...) a String no podemos usar el toString() pero sí el //String.valueOf(var);// * Existen también los //StringBuffer//, que son tratados como clases (por referencia), tienen otros métodos como el //append, delete e insert//... Estos //StringBuffers// pueden truncar cadenas o extenderlas mediante carácteres nulos gracias al método //setLength// * Métodos para comparar Strings: * //str.equals(str2)//: Compara dos cadenas * //str.equalsIgnoreCase(str2)//: Compara dos cadenas ignorando mayusculas y minusculas * Secuencias de escape: \' ' \" " \\ \ \n Nueva línea \t Tablulador ==== Bucle ForEach ==== Los demás bucles son idénticos a C#. Este tiene la siguiente sintaxis: String[] strArray = {"alto", "bajo", "mediano"}; for(String car : strstrArray) System.out.println(car); ===== Propiedades de una clase ===== ==== Palabra clave 'this' ==== Como ya sabemos, podemos usar esta palabra, dentro de una clase, para acceder al propio objeto: this.propiedad; this.metodo(parametro);. Pero también podemos usarla dentro de los constructores para llamar a otros constructores: this(), pero para hacer esto debe de ser la primera línea del compilador. constructor (int i) { this(i, 2); } ==== Estaticos ==== * Las variables y métodos static son llamados "de clase". * Sólo hay uno en todo el programa. * No necesitan inicializar la clase para llamarlos. * Los métodos estáticos no pueden acceder a "this". * Se puede colocar un bloque inicializador de variables staticas dentro de la clase, este bloque será llamado cuando se acceda por primera vez a la clase que contiene las estáticas (ya sea haciendo un new o accediendo a los estáticos). * El bloque de estáticos se escribirá así: static { ... Inicializaciones estáticas ... } Hemos de recordar que no es necesario un objeto para llamar a un método estático, pero sí que se pueden llamar desde un objeto. ==== Método finalize ==== Podemos añadir a nuestra clase un método llamado finalize, este método hace de destructor, es decir, cuando el objeto es destruido se llama a este método. En este método es recomendable poner a null todas las referencias. ==== Herencia ==== * Para que una clase herede de otra se usa la palabra 'extends', sólo se puede heredar de una clase: **public class Form extends Frame {}** * Para que una clase herede también de una interface usaremos 'implements', se pueden implementar tantas interfaces como se quiera: **public class Form extends Frame implements ActionListener {}** * El orden de llamada de los constructores será primero el constructor por defecto de la clase base y luego el segundo la clase derivada, a la que hemos llamado. Siempre empezará por la más base de todas. * Podemos elegir a qué constructor de la clase base llamar mediante la cláusula 'super'. Pero ha de ser la primera línea del constructor y no se puede combinar con la clausula 'this' para llamar a otro constructor de dicha clase. ==== Tabla de modificadores de acceso ==== A Propia clase B Derivada en el mismo paquete C Derivada en otro paquete D Otra clase en el mismo paquete E Otra clase en otro paquete F Modificador: Sin especificar ----------------------------------------------- private F protected public A x x x x B x x x C x x D x x E x ==== Sobreescritura ==== * Puedes sobreescribir los métodos de tu clase base únicamente volviendolos a codificar. * Para acceder desde tu clase a un método de su clase base ya sobreescrito debemos indicarlo con la palabra 'super': super.Draw(); ==== Clases Abstractas ==== * No se pueden crear objetos de estas clases, sólo sirven para que otras clases deriven de ellas y se tenga la __obligación__ de codificar sus métodos abstractos. Para codificarlos sólo hay que sobreescribirlos. * Los métodos abstractos no deben tener cuerpo, ni siquiera se ha de codificar los corchetes: **protected abstract String getData();** * Su diferencia con las interfaces es que estas últimas no pueden codificarse métodos no abstractos. ==== Clausula final ==== * Al poner 'final' delante de un método impedimos que este pueda sobreescribirse. * Al poner 'final' delante de una clase impedimos que de esta pueda heredarse. ===== Otros elementos del lenguaje ===== ==== Clase System.lang.Object ==== Es de esta clase de la que toda clase hereda en java (clase 'object' de C#). Tiene algunos métodos que pueden sernos de utilidad: * **clone** Copiar un objeto * **equals** Indica si un objeto es igual a otro * **finalize** Al método que se llama al destruir el objeto * **getClass** Devuelve el objeto Class de la clase del objeto * **toString** Representa el objeto en string ==== Paquetes ==== Antes de hacer los 'import' podemos indicar que el archivo de código en el que estamos trabajando corresponde a un paquete en concreto, para ello usaremos la palabra 'package ;'.Con los 'import' lo que hacemos realmente son accesos directos a los paquetes ya creados. ==== Enumeraciones ==== Podemos crear enumeraciones como en C#, aunque cambia algo: * Declaración: enum abc {a, b, c, d}; * Declarar variable y asignar: abc letra = abc.a; * Uso en if: if (letra == abc.b) {} * Uso en switch: switch(letra) { case (a): break;} * [[highlevel:java:xtra#enumeraciones|Enumeraciones en Xtra]] ==== Interfaces ==== * Se declaran: **interface nombre {}** * Los métodos que contengan las interfaces no pueden tener cuerpo y una vez implementados en clases estos han de ser públicos. * Cuando una clase hereda de una o varias interfaces hemos de indicarlo usando la palabra 'implements' seguido del nombre de la\s interfaz\ces. * Para indicar que una interface hereda de una o varias interfaces usaremos la palabra extends. * Cuando una clase hereda de una interface o varias esta ha de implementar todos los métodos de las que hereda. * Las interfaces pueden contener campos (propiedades). * Recuerda que una vez heredemos de una interfaz podemos usar un objeto de esa clase como un objeto de dicha interfaz. ==== Clases internas anónimas ==== Podemos crear clases dentro de otras, eso ya lo sabemos, pero podemos ampliar la definición de una: class App { private App () { new App2 () { public void print() { System.out.println("Clase interna anónima"); } }.print(); } } class App2 { private int i = 3; } ==== Excepciones ==== * Las excepciones en java son clases derivadas de Throwable. * Se gestionan mediante el try\catch. * Pueden haber varios catch. Pero no puede haber un try sin catch ni un catch sin try. * En una porción de código podemos hacer un try\catch que controlemos una excepción de "array fuera de límites", pero ese código puede lanzar cualquier otra excepción, podemos controlar las demás haciendo: try{} catch(ArrayIndexOut... exc){} catch (Throwable exc){} ya que todas las excepciones heredan de Throwable. * Podemos lanzar excepciones mediante throw: **throw new ArithmeticException();** * Podemos recoger una definición de la excepción con: getMessage. * Podemos añadir una clausula más: try\catch\finally. 'finally' se usa para acabar ese try\catch. Por ejemplo en el try se abre una conexión de red, se produce un error, pasa al catch, pero en el finally se cierra. * Podemos indicar que un método lanza excepciones mediante la clausula 'throws' seguida de la lista de excepciones separadas por comas: **public void Read () throws java.io.IOException {}** * Podemos obviar un try\catch en la llamada a un método que lanza una excepción si en el método donde se realiza dicha llamada indicamos que lanza esa excepción. ==== Aserciones ==== * La aserción, **assert**, es una directiva usada para el control de errores. * Puedes activarlas mediante el parámetro -enableassertions. * Su uso básicamente es el de activarlas cuando estás testeando tus clases, para ver si se llega a ciertas partes del código que no se debería. * Su sintaxis es: //assert ;// * Si la expresión boleana es false lanza una excepción AssertionError. ===== Clases interesantes ===== ==== La clase Math ==== En esta clase encontraremos algunos métodos para otras operaciones matemáticas: * **E** número 'e' (2.7) * **PI** número pi (3.14) * **sin** seno * **cos** coseno * **tan** tangente * **asin** arcoseno * **acos** arcocoseno * **atan** arcotangente * **exp** eleva el número 'e' a la potencia indicada * **log** logaritmo de valor * **sqrt** raíz cuadrada * **pow** eleva un valor indicado a la potencia indiada * **round** redondea un double\float indicado a int * **abs** valor absoluto ==== java.io.File ==== Nos permite obtener información de un fichero\directorio (saber tipo, fecha de creación, su ruta completa, todos sus directorios\ficheros, si se puede leer\escribir...). Y operar con él (crear un nuevo fichero, directorio, borrar...). ==== java.io.BufferedReader ==== Esta clase te permite realizar una gestión más sencilla de streams de entrada mediante métodos como readline que devuelven strings de líneas, nos puede servir para introducción por teclado, lectura de un fichero... BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("mujeres.txt"))); BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); ==== java.lang.System ==== Esta clase contiene métodos de control y utilidades de la máquina de java, no necesita instanciarse... Mira sus métodos: * **exit** Cierra la aplicación. Indicando 0 significará un cierre normal del sistema. * **arraycopy** Copia un array. * **gc** Lanza el recolector de basura. * **currentTimeMillis** Devuelve la hora actual en milisegundos * **in\out\err** Streams básicos del sistema * **setIn\setOut\setErr** Reasignan los Streams básicos del sistema * **getenv** Para gestionar el entorno de sistema * **getProperties\setProperty\getProperty** Para gestionar propiedades del sistema ==== java.lang.Runtime ==== * Esta clase nos permite acceder al sistema donde se está ejecutando la JVM. * Podemos conseguir un objeto Runtime mediante el método //Runtime.getRuntime()//. * Métodos: * **avaiableProcessors** Procesadores del sistema * **exec** Ejecución de un proceso de sistema * **freeMemory** Indicación de la memoria libre del sistema * **totalMemory** Indicación de la memoria total del sistema ===== Interfaces interesantes ===== ==== java.util.Enumeration ==== El uso de esta interface es una forma de recorrer fácilmente un grupo de elementos. Únicamente contiene dos métodos: 'nextElement' que devuelve el siguiente elemento y 'hasMoreElements' que indica si contiene más elementos a parte de los ya dados. while (e.hasMoreElements()) System.out.println(e.nextElement()); ==== java.lang.Comparable ==== Interface usada para comparar objetos y, poder así, ordenarlos. Contiene un método llamado compareTo, a este método se le pasa un Object (B) y este es comparado con el objeto donde se llama a dicho método (A). Devuelve un int. * Si A < B el int devuelto debe ser menor que cero, negativo. * Si A > B el int devuelto debe ser positivo. * Si A = B el int devuelto debe ser 0. Una forma de implementar esto de forma sencilla, es, si se han de comparar varios ints restarlos y devolver el resultado. ===== Concretamente... ===== ==== Colecciones ==== === java.util.Vector === Array dinámico. Se le declara indicandole una dimensión que ocupará en memoria, y se le introducen elementos, si esa dimensión es rebasada actuará ampliandola según hallamos indicado. * Para indicar como se incrementará la dimensión del vector usaremos su constructor. * El constructor por defecto inicializa la dimensión a 10. Cada vez que esta sea rebasada se duplicará. * El constructor al que se le pasa un sólo int inicia la dimensión del Vector según el int indicado. Cuando esta sea rebasada se duplicará. * El constructoral que se le pasan dos ints, nos permite mediante el primer int indicar su dimensión inicial, el segundo indica cuantas posiciones se incrementa cada vez que la dimensión es rebasada. * Métodos: * **capacity** Nos devuelve su dimensión actual * **size** Número de elementos introducidos * **addElement** Añade un elemento * **removeElement** Elimina el elemento indicado * **removeElementAt** Elimina el elemento de la posición indicada * **insertElementAt** Inserta un elemento en la posición indicada * **trimToSize** Iguala la dimensión al número e objetos insertados * **setSize** Fuerza el número de elemntos insertados * **elements** Devuelve una Enumeration del Vector * **iterator** Devuelve un Iterator del Vector. === java.util.Stack === Representa un Vector en forma de pila (tipo FIFO, primero en entrar, primero en salir). Contiene los siguientes métodos: * **push** Introduce un elemento en la pila * **pop** Saca un elemento de la pila * **peek** Devuelve el último elemento de la pila sin sacarlo === Clase abstracta java.util.Dictionary === Usada para derivar clases que ordenen sus elementos mediante clave\valor, esto es que no se relaciona el elemento por un índice sino por otro objeto. Una subclase de esta sería Hashtable. \\ Los métodos que implementa son: * **size** Devuelve el número de entradas insertadas. * **get** Pasándole un Object de tevuelve otro del mismo tipo * **put** Indicando dos Objects inserta el primero como clave y el segundo como valor. * **keys** Devuelve una Enumeration con todas sus claves. * **values** Devuelve una Enumeration con todos sus valores. === Otras anotaciones sobre collections === * La clase //Bitset// representa un array de bits, true o (por defecto) false, nos permite hacer hacer sobre él operaciones lógicas como el AND, el OR, el XOR... * Una lista enlazada está representada en la API de java como la clase LinkedList. Un árbol binario se representa en la clase TreeSet. * La clase ArrayList es idéntica a la Vector, pero la diferencia es que esta última es segura frente a threads. Por lo que si no usas threads en tu programa utiliza ArrayList, será más óptimo. * Implementar la clase abstracta 'AbstractCollection' te permitirá crear colecciones más fácilmente. * Las bases de todos los elementos de Collections son las interfaces: //Collection// e //Iterator//. ==== Streams ==== * Las clases de entrada y salida de datos son: //java.io.InputStream//, la de entrada, y //java.io.OutputStream//, la de salida. * De estas clases heredan otras con las que se opera más adecuadamente: === java.io.FileInputStream === Nos permite leer un fichero pasado por su constructor, sus métodos: * **avaiable()** Lo que nos falta hasta llegar al final del archivo. * **read()** Leer una serie de bytes. * **skip()** Saltarnos sin leer una serie de bytes. * **close()** Cerrar el archivo. === java.io.FileOutputStream === * Nos permitirá escribir un fichero indicado en el constructor, además, en el constructor podemos indicar un bool (append) si es true lo escrito se hará al final, si es false el archivo será sobreescrito o creado. Se usa igual que //java.io.FileInputStream// sustituyendo el read por el write, evidentemente sin tener avaiable o skip. * Podemos tratar buffers de memoria (arrays de bytes) mediante las clases //ByteArrayInputStream//, para leer, y //ByteArrayOutputStream//, para escribir. * Para escribir en //raw// usaremos //DataOutputStream// y //DataInputStream.// * Podemos, también, hacer un acceso aleatorio a un archivo, esto es que no tiene por qué ser secuencial, para esto usaremos la clase RandomAccessFile, que gracias a su método //seek// podemos colocarnos en cualquier parte del código. ==== Multitarea ==== * La clase que representa los hilos de ejecución es java.lang.Thread. * Los métodos que pueden sernos útiles de esta clase son: * **activeCount** Te dice el número de hilos activos en ese hilo * **checkAccess** Te indica si ese hilo puede ser modificado * **get/setName** Puedes gestionar el nombre del hilo * **getPriority** Puedes gestionar la prioridad del hilo, esta prioridad viende de las constantes estáticas: Thread.MAX_PRIORITY, Thread.MIN_PRIORITY y Thread.NORM_PRIORITY * **isAlive** Indica si el hilo está vivo * **join** Espera hasta que el hilo muera antes de continuar, puedes indicar un número de milisegundos a esperar. * **sleep** Pausa la ejecución del hilo los milisegundos indicados. * **start** Inicia el hilo * Para obtener el hilo principal del programa usaremos //Thread.currentThread();//. * Hay dos formas de usar los Threads, una es heredar de la clase Thread y colocar ahí tu código y la otra es heredar de la interfaz //java.lang.Runnable//, esta únicamente te obliga a implementar el método run. Cuando tú crees un objeto Thread, al constructor le pasas tu objeto Runnable, el método run será llamado entonces. * **synchronized** te permite bloquear un método o un bloque de código para que no sean accedidos por otro hilo. * Para hacer que un método sea bloquedado sería: **synchronized ValorRetorno Nombre (Parámetros) {}** * Para bloquear una porción de código: **synchronized ( ) { }** * Si tienes varias rutinas trabajando en multihilo, una lee y la otra escribe, puede que el orden se rompa. Para poder controlar esto todos los objetos contienen los métodos wait, notify y notifyAll (heredados de la clase Object). Cuando llamas a wait, el hilo en el que se estaba usando ese objeto queda parado hasta que no se llama a los métodos notify o notifyAll de dicho objeto.