Diferencia entre final, finally y finalize()

Si tienes que liberar un fichero gestionado por un objeto, ¿que harías, llamar al método finalize(), o introducir una clausula finally?
  • final: decalaración de una constante.
  • El método finalize(): Algunos lenguajes de programación orientados a objetos requieren que el programador destruya explícitamente los objetos cuando dejan de utilizarse. Sin embargo en java, la JVM se responsabiliza de reclamar la memoria reservada por los diferentes objetos estos quedan fuera de alcance (proceso denominado «garbage collection«, o de limpieza), por lo que se libera al programador de esta tarea. Hay dos importantes características del proceso de limpieza: 1) cuando un object sale de alcance, inmediatamente se le considero que pertenece a la «colección basura». Pero no es del todo preciso. Al salir de alcance, lo que ocurre es que se le marca como candidato para la «colección basura», y el proceso limpieza (que gestiona la colección) periódicamente va reclamando estos objetos en memoria fuera de alcance sin referenciar, de modo recursivo. Lo malo es que esto no ocurre en momentos predeterminados, pues no existe una especificación exacta en la JVM de cuando se ejecutará el proceso de limpieza.
    Si el proceso se ejecuta antes de que un objeto haya pasado a la colección-de-basura, el runtime de java invoca al método finalize() del objeto, permitiendo que este pueda realizar cualquiera las operaciones que liberen los recursos demandados al sistema tales como ficheros o sockets abiertos. Este método finalize() se declara como: protected void finalize() throws Throwable. El proceso de limpieza se ejecuta como un hilo demonio de bajo-nivel y, en general, para este tipo de hilos, no es esencial que el hilo se complete antes de que la aplicación termine.
    He aquí el problema, pues aunque pueda utilizarse el método finalize para realizar las operaciones de limpieza, el hilo recolector encargado de llamar al método finalize() de los objetos podría ejecutarse de un modo impredecible.
  • La declaración finally en un bloque de código implica la liberación explícita de cualquiera de los recursos externos que puedan ser mantenidos. A diferencia del método finalize(), la declaración finally no depende del proceso de limpieza del recolector de basura. La liberación de recursos dentro de un bloque finally es más aconsejable pues se garantiza que el código dentro del finally siempre será ejecutado incluso cuando haya una excepción inesperada en tiempo de ejecución.
Diferencia entre final, finally y finalize()

Clases y métodos genéricos

Clases genéricas

public class UseTwo<T, X> {
	T one;
	X two;

	UseTwo(T one, X two) {
		this.one = one;
		this.two = two;
	}

	T getT() {
		return one;
	}

	X getX() {
		return two;
	}

	// test it by creating it with <String, Integer>
	public static void main(String[] args) {
		UseTwo<String, Integer> twos = new UseTwo<String, Integer>("foo", 42);
		String theT = twos.getT(); // returns a String
		int theX = twos.getX(); // returns Integer, unboxes to int
	}
}

Métodos genéricos:

public class CreateAnArrayList {
	public <T> void makeArrayList(T t) { // take an object of an unknown type and use a
	                                     // "T" to represent the type
		List<T> list = new ArrayList<T>(); // now we can create the
		// list using "T"
		list.add(t);

		System.out.println(list.get(0).toString());
	}

	public static void main(String[] args) {
		CreateAnArrayList arr = new CreateAnArrayList();
		Horse h = new Horse(4, "eno");
		arr.makeArrayList(h);
	}
}
Clases y métodos genéricos

‘Collection’ en java 1.6

List: un conjunto de cosas
Set: cosas únicas
Map: cosas con un único ID (identificador)
Queues: cosas organizadas en orden a cómo deben ser procesadas.

Ordenado (Ordered): Significa que la colección se puede iterar en un orden específico no aleatorio.

Clasificado (Sorted): el orden de la colección es determinado acorde a unas reglas, basadas en las propiedades de los objetos que la componen. La ordenación natural: alfabética o numérica.

Comparable vs Comparator (artículo)

A través de la Interfaz ‘Comparable’ que define como la instancia de una clase puede ser comparada con otra (la clase persona se ordena por el nombre).

java.lang.Comparable
java.util.Comparator
int objOne.compareTo(objTwo)
int compare(objOne, objTwo)
Returns
negative if objOne < objTwo
zero if objOne == objTwo
positive if objOne > objTwo
Same as Comparable
You must modify the class whose instances you want to sort. You build a class separate from the class whose instances you want to sort.
Only one sort sequence can be created
Many sort sequences can be created
Implemented frequently in the API by:

String, Wrapper classes, Date, Calendar...
Meant to be implemented to sort instances of third-party classes.
public class Employee implements Comparable<Employee>
{
private String name;
private int age;

public Employee(String name, int age)
{
this.name = name;
this.age = age;
}

public int compareTo(Employee e)
{
//comparison strategy
}

public static void main(String[] args)
{
List<Employee> employeeList = new ArrayList<Employee>();
employeeList.add( new Employee("Tim", 10) );
employeeList.add( new Employee("Rolvin", 11) );
employeeList.add( new Employee("Gerald", 12) );

Collections.sort(employeeList);
}
}

A través de la interfaz ‘Comparator’: se pueden implementar otras clases que implementan otros tipos de ordenación (la clase persona se ordena por nombre, o por apellido o por edad).

public class SortByName implements Comparator<Employee>
{
public int compare(Employee e1, Employee e2)
{
//comparison strategy here
}
}
public class SortByAge implements Comparator<Employee>
{
public int compare(Employee e1, Employee e2)
{
//comparison strategy here
}
}
public static void main(String[] args)
{
List<Employee> employeeList = new ArrayList<Employee>();
employeeList.add( new Employee("Tim", 10) );
employeeList.add( new Employee("Rolvin", 11) );
employeeList.add( new Employee("Gerald", 12) );

Collections.sort(employeeList, new SortByName() );//sort by name;
Collections.sort(employeeList, new SortByAge() );//sort by age;

}

La interfaz List

Sus implementaciones son ordenadas por el index.

get(int index), indexOf(Object o), add(int index, Object obj)

ArrayList: es un array con la capacidad de crecer. Ofrece una rápida iteración y acceso. Ordered pero no Sorted.
Vector: lo mismo que ArrayList pero es Synchronized.
LinkedList: mantiene el orden de los objetos según su inserción. Más lento en la iteración que el ArrayList pero más rápido en la inserción y eliminación. Implementa la interfaz java.util.Queue, que proporciona los métodos:

java.util.Queue
peek(), poll(), and offer().

El método peek devuelve, pero no borra, la cabecera de la cola.
El método poll devuelve y borra la cabecera de la cola
El método add inserta un elemento a no ser que se supere la capacidad de la cola, en este caso se lanza una IllegalStateException.
El método offer es igual que add pero devuelve false si existe algun error en la insercción.

La interfaz Set

No permite duplicados.
HashSet: es ‘unsorted and unordered’ no se puede ni ordenar ni clasificar. Usa el hasCode() de los objetos para insertarlos. Para colecciones sin duplicados pero no importa el orden en que se recorran
LinkedHashSet: es una versión ordenada de HashSet. Ordena los elementos en función del orden de inserción.
TreeSet: usa la estructura de árbol Red-Black. Ordena los elementos según se insertan en orden ascendente. Implementa ‘NavigableSet’. Puedes personalizar la clasificación.

La interfaz Map

Tiene un único identificador para un valor. (key /value)
HashMap: es ‘unsorted and unordered’ no se puede ni ordenar ni clasificar. Permite la llave nula y múltiples valores nulos.
HashTable: similar a HashMap pero es Synchronized. Ningún elemento debe ser nulo. LinkedHashmap: mantiene el orden de inserción. TreeMap: Ordena los elementos según se insertan en orden ascendente. Implementa ‘NavigableSet’. Puedes personalizar la clasificación.

La interfaz Queue

Como una pila FIFO (First In – First Out).
PriorityQueue: es una lista de prioridades (Priority In – Priority Out). La prioridad viene determinada por la clasificación de los elementos.

CLASE
MAP
SET
LIST
ORDERED
SORTED
HashMap
X
 
 
NO
NO
HashTable
X
 
 
NO
NO
TreeMap
X
 
 
SORTED
By natural order or custom comparison rules
LinkedHashMap
X
 
 
By insertion order or last access order
NO
HashSet
 
X
 
NO
NO
TreeSet
 
X
 
SORTED
By natural order or

custom comparison rules
LinkedHashSet
 
X
 
By insertion order
NO
ArrayList
 
 
X
BY INDEX
NO
Vecctor
 
 
X
BY INDEX
NO
LinkedList
 
 
X
BY INDEX
NO
PriorityQueue
 
 
 
SORTED
By TO-DO order

ArrayList

Ventaja sobre un array: a) crece dinámicamente, b)inserción y búsqueda mejoradas.
Cómo ordenar un ArrayList:

ArrayList<String> stuff = new ArrayList<String>();
stuff.add("Denver");
stuff.add("Boulder");
stuff.add("Vail");
stuff.add("Aspen");
stuff.add("Telluride");
System.out.println("unsorted " + stuff);
Collections.sort(stuff);
System.out.println("sorted " + stuff);
unsorted [Denver, Boulder, Vail, Aspen, Telluride]
sorted [Aspen, Boulder, Denver, Telluride, Vail]

Utilizando la ordenación de los arrays.

Arrays.sort(arrayToSort)

Búsqueda en Arrays y Collection:
–   Utilizan el método BinarySearch(): Arrays.binarySearch(arrayList,»one»)
–   Las búsquedas satisfactorias devuelven un ‘int’ que representa el índice del elemento.
–   Las búsquedas no satisfactorias devuelven in ‘int’ que representa el punto de insercción.

Convertir Arrays en Listas

String[] sa = {"one", "two", "three", "four"};
List sList = Arrays.asList(sa);

Backed Collections

TreeMap<String, String> map = new TreeMap<String, String>();
map.put("a", "ant"); map.put("d", "dog"); map.put("h", "horse");
SortedMap<String, String> submap;
submap = map.subMap("b", "g"); // #1 create a backed collection
System.out.println(map + " " + submap); // #2 show contents
map.put("b", "bat"); // #3 add to original
submap.put("f", "fish"); // #4 add to copy
map.put("r", "raccoon"); // #5 add to original - out of range
// submap.put("p", "pig"); // #6 add to copy - out of range
System.out.println(map + " " + submap); // #7 show final contents
{a=ant, d=dog, h=horse} {d=dog}
{a=ant, b=bat, d=dog, f=fish, h=horse, r=raccoon} {b=bat, d=dog, f=fish}

TreeMap.subMap(desde el valor inicial, hasta el valor final);
La subcoleción registra las modificaciones realizadas en la colección a la que pertenece.
El dato insertado en la subcoleción también se registra en la colección.

headSet: Empieza al principio y termina en el dato pasado como parámetro.
TreeSet.headSet();                        TreeMap.headSet();

subSet: Indica cuando empieza y acaba con los parámetros.
TreeSet.subSet();                           TreeMap.subSet();

TailSet: desde el parámetro pasado como argumento hasta el final.
TreeSet.tailSet();                            TreeMap.tailSet();

Bibliografia:
http://java.sun.com/docs/books/tutorial/collections/interfaces/index.html
– Libro:  SCJP Sun Certified Programmer for Java 6 Exam 310-065

‘Collection’ en java 1.6

Sobrecargando Widening, Boxing, Varargs

Widening

Las 19 siguientes conversiones de tipos primitivos son llamados ‘widening primitive conversions’:

byte to short, int, long, float, or double
short to int, long, float, or double
char to int, long, float, or double
int to long, float, or double
long to float or double
float to double

No pierden información

class Test {
   public static void main(String[] args) {
      int big = 1234567890;
      float approx = big;
      System.out.println(big - (int)approx);
   }
}

Consola:

-46

Indica la información que se ha perdido durante la conversión de tipos, pero porque el tipo float no es preciso con 9 digitos.

Narrowing

Las 23 siguientes conversiones de tipos primitivos son llamados ‘narrowing primitive conversions’:

byte to char
short to byte or char
char to byte or short
int to byte, short, or char
long to byte, short, char, or int
float to byte, short, char, int, or long
double to byte, short, char, int, long, or float

Se pierde valor o precision.

Autoboxing

Para insertar un int en una colección, lo que se hace automaticamente es:

1.- BOX guardar la variable en una clase que la envuelva(wrapper), en este caso Integer.
2.- se guarda en la collection.
3.- cuando quieras recoger el dato se hace UNBOX del Integer usando intValue(), te devuelve en int.

Varargs

Hay veces que necesitas enviar a un metodo, muchas instancias de un mismo objeto. Pero en tiempo de compilacion no sabes cuantas. En vez de enviar un array o una collection, puedes usar: ‘variable arity parameters’ ó como se les conoce formalmente: ‘varargs‘.

class VarGreeter {
   public static void printGreeting(String... names) {
      for (String n : names) {
        System.out.println("Hello " + n + ". ");
      }
   }

   public static void main(String[] args) {
      printGreeting("Paul", "Sue");
   }
}

Sobrecargando Widening, Boxing, Varargs

W -> B -> V
(WB: NO)
(BW: SI)
(VW, VB: SI)

1. Widening wins over boxing and Varargs
2. Boxing wins over Varargs
3. Widening of reference variable depends on inheritance(so, Integer cannot be widened to Long. But, Integer widened to Number).
4. Widen and boxing is not possible
5. Boxing and widening is possible
6. Varargs can be combined with either boxing or widening

Sobrecargando Widening, Boxing, Varargs

POO Overriding(Sobreescritura) vs Overloading(sobrecarga)

Del libro: SCJP Sun Certified Programmer for Java 6 Exam 310-065

Métodos Sobrecargados (Overloaded)

Métodos Sobrescritos (Overridden)

Argumento(s)

Debe cambiar

No debe cambiar

Tipo devuelto
(Return type)

No cambiar.

No cambiar excepto para ‘covariant returns’.

Excepciones

No cambiar.

Se puede reducer o eliminar

No se debe lanzar una nueva excepción o ampliar la existente.

Acceso

No cambiar

Se puede hacer más restrictiva

Invocación

El tipo de referencia determina que versión de sobrecarga (basada en los tipos de argumentos declarados) ha sido seleccionada. Ocurre en tiempo de compilación. El método invocado todavía es una invocación virtual del método, en tiempo de ejecución, pero el compilador sabe la firma del método que es invocado. Así, en tiempo de ejecución, el argumento emparejado ya se habrá llevado a cabo, no solo en la clase en la que el método reside

El tipo de objeto (el tipo de la instancia actual en la Heap) determina que método es seleccionado. Sucede en tiempo de ejecución.

Reglas a seguir para sobrescribir un método:
– La lista de argumentos debe coincidir con el método sobrescrito.
– El tipo devuelto debe ser el mismo, o un subtipo de.
– El acceso no puede ser más restrictivo que el método sobrescrito.
– El acceso puede ser menos restrictivo que el método sobrescrito.
– Las instancias de los métodos puede ser sobrescritos solamente si son herederos de la subclase.
– El método sobrescrito puede lanzar cualquier excepción ‘uncheked’ en tiempo de ejecución.
– El método sobrescrito no debe lanzar excepciones ‘checked’ que son nuevas o mas amplias que las declaradas.
– El método sobrescrito puede lanzar excepciones limitadas o menos excepciones.
– No sobrescribir métodos ‘final’.
– No sobrescribir métodos ‘static’.
– Si un método no puede ser heredado, no se puede sobrescribir.
Los métodos sobrecargados:
– Deben cambiar la lista de argumentos.
– Pueden cambiar el tipo devuelto.
– Pueden cambiar los modificadores de acceso.
– Pueden declarar nuevas excepciones o ampliar las existentes.
– Un método puede ser sobreescrito en la misma clase o en una subclase

Un ejemplo:


package com.codingdojo.pomodoro;
public class Animal {
protected static int cont = 0;
protected int patas;
protected String comida;
protected String sonido;

public Animal(int patas, String sonido) {
this.patas = patas;
this.sonido = sonido;
++cont;
}

public void come(String comida) {
this.comida = comida;
}

public int getCont() {
return cont;
}

public String toString() {
return "Un " + getClass().getName() + " come: " + comida + ", "+ "tiene " + patas + " patas" + ", " + "y " + sonido;
}
}

package com.codingdojo.pomodoro;
public class Horse extends Animal {
public Horse(int patas, String sonido) {
super(patas, sonido);
}

// sobrecarga(overload) de operadores
public void come(String apple, String eno, String salt) {
comida = apple + ", " + eno + ", " + salt;
}
}

package com.codingdojo.pomodoro;
public class Dog extends Animal {
public Dog(int patas, String sonido) {
super(patas, sonido);
}

}

package com.codingdojo.pomodoro;
public class Cat extends Animal {
public Cat(int patas, String sonido) {
super(patas, sonido);
}

// sobreescritura(overridding) de operadores
public void come(String leche) {
comida = "un poco de: " + leche;
}

}

package com.codingdojo.pomodoro;
import java.util.ArrayList;
import java.util.List;

public class AnimalTest {
public static void main(String[] args) {
Animal animal = new Animal(0, "--");
Horse horse = new Horse(4, "relincha");
Dog dog = new Dog(4, "ladra");
Cat cat = new Cat(4, "maulla");

List<Animal> list = new ArrayList<Animal>();
list.add(animal);
list.add(horse);
list.add(cat);
list.add(dog);

for (Animal animalito : list) {
if (animalito instanceof Horse) {
((Horse) animalito).come("manzanas", "eno", "sal");
}else if (animalito instanceof Dog) {
((Dog) animalito).come("pienso");
}else if (animalito instanceof Cat) {
((Cat) animalito).come("Leche");
}else {
animalito.come("lo que puede");
}

System.out.println(animalito.toString());
}

System.out.println("Numero de instacias de Animal: "+animal.getCont());
}
}

Salida de consola:

Un com.codingdojo.pomodoro.Animal come: lo que puede, tiene 0 patas, y --
Un com.codingdojo.pomodoro.Horse come: manzanas, eno, sal, tiene 4 patas, y relincha
Un com.codingdojo.pomodoro.Cat come: un poco de: Leche, tiene 4 patas, y maulla
Un com.codingdojo.pomodoro.Dog come: pienso, tiene 4 patas, y ladra
Numero de instacias de Animal: 4
POO Overriding(Sobreescritura) vs Overloading(sobrecarga)

Diferencias entre STACK y HEAP de la JVM

STACK HEAP
Almacena Variables locales Objetos (clases, métodos, instancias)
Nunca se puede manipular directamente Se puede redimensionar y tiene el ‘Garbage Collector’
Tiene acceso al procesador, ‘stack pointer’

no

La memoria no necesita ser contigua Idem
Cada hilo tiene un stack Común a toda la JVM
OutOfMemory No tiene espacio para un nuevo hilo. Necesita más tamaño.
StackOverflow Requiere más espacio del permitido

·

Ejemplo:

var blue
var red
ref 0x456783= (Heap reference)
var tom
ref 0x498702= (Heap reference)
var diane
Heap (0x4567= 83)
name = Susan
age = 26
city= London
height= 5’7
sex= female

Heap (0x4987= 02)
name= Paul
age= 21
city = Glasgow
height = 6’0
sex = male

Ejemplo grafico
Bibliografia:
Diferencias entre STACK y HEAP de la JVM

¿Qué es Rake?

Del diccionario inglés:
-nombre: rastrillo, calavera.
-verbo: examinar, registrar por.
El otro día publiqué una traducción de un artículo de Kent R. Spillner sobre herramientas de contrucción (builds). Elogiaba vehementemente una herramienta: Rake.
Voy a intentar satisfacer mi curiosidad. Sobre todo: ¿es compatible con proyectos java? ¿puedo cambiar mi ‘build‘ de Maven por uno de Rake?.
Rake esta hecho con Ruby [Ruby es un lenguaje de programación interpretado, reflexivo y orientado a objetos. Combina una sintáxis inspirada en Python, Perl con características de programación orientada a objetos similares a Smalltalk. Comparte también funcionalidad con otros lenguajes de programación como Lisp, Lua, Dylan y CLU. Ruby es un lenguaje de programación interpretado en una sola pasada y su implementación oficial es distribuida bajo una licencia de software libre].
Rake tiene las siguientes caracteristicas:
– los ficheros Rake, reakefiles, idénticos a los ‘makefiles‘ estan completamente definidos en la sintáxis de Ruby. No hay que editar ficheros XML. Los Makefile no tiene una sintáxis rara sobre la que preocuparse (¿es un tabulado o un espacio?).
– Los usuarios pueden especificar tareas con prerequisitos.
– Rake soporta patrones de regla para sintetizar tareas implícitas.
– Listas de ficheros flexibles que trabajan como arrays, pero saben como manipular ficheros y rutas.
– Una libreria de tareas pre-empaquetadas para crear fácilmente construcciones rakefiles.
Documentación oficial
Herramientas para Java, basadas en Rake: buildr, Raven.
¿Qué es Rake?