[Las cosas que no interesan]
lunes may 28, 2007
SCJP for JSE5 - 7
1. Variables locales y modificadores de acceso
Las variables locales son las que se declaran dentro de los métodos y el único modificador que se puede usar con ellas es final, esto incluye los parámetros que recibe un método. Las variables primitivas marcadas como final no pueden ser modificadas y a las variables de referencia marcadas como final, no se les puede asignar un nuevo objeto.
2. Otras consideraciones para el modificador final
- Los métodos marcados como final no pueden ser sobreescritos.
- Los argumentos marcados como final no pueden ser modificados.
public int consultarDatos(final int clave){
clave = 23; //error de compilación!!
}
Este método no compila por que se está intentando modificar una variable final.
- Las clases final no pueden ser heredadas.
3. Otros modificadores
- abstract: El modificador abstract solo aplica para las clases y los métodos. Un método abstracto es el que ha sido declarado pero no tiene implementación y solo pueden existir dentro de clases abstractas. La primera clase concreta que hereda una clase abstracta, debe implementar todos sus métodos abstractos. Por clase concreta se quiere decir clase no abstracta.
- synchronized: este modificador solo aplica para los métodos. Un método sincronizado solo puede ser ejecutado por un hilo a la vez, esto se verá más adelante cuando se trate el tema de concurrencia.
- native: este modificador solo aplica para los métodos. Un método nativo es implementando normalmente en otro lenguaje para cada plataforma y en la clase solo se declara (como un método abstracto).
- strictfp: aplica para clases y métodos. Una clase o método marcada como strictfp se adhiere al estándar IEEE 754, no es necesario profundizar más (solo si se tiene curiosidad).
- transient: solo aplica para atributos de instancia. Los atributos marcados como transient son ignorados cuando se serializa una clase (tema tratado más adelante).
- volatile: solo aplica para atributos de instancia. Es un modificador utilizado cuando se trabaja con hilos, e indica a la máquina virtual que siempre acceda a una copia de la variable. Esto es complejo y se tratará junto con todo el tema de concurrencia.
4. Combinaciones entre modificadores
Los modificadores (que no son de acceso) que se pueden usar con los métodos son: final, abstract, synchronized y strictfp. Todos estos modificadores se pueden usar conjuntamente, pero no todos con todos. Las combinaciones legales se resumen en la siguiente tabla (una 'X' indica que se pueden combinar, una 'O' indica que no):
| final | abstract | synchronized | strictfp | |
| final | X | O | X | X |
| abstract | O | X | O | O |
| synchronized | X | O | X | X |
| strictfp | X | O | X | X |
Por ejemplo el modificador synchronized no se puede usar con abstract.
Los modificadores (que no son de acceso) que se pueden usar con atributos de instancia son: final, transient y volatile. Esta es la tabla para combinarlos:
| final | transient | volatile | |
| final | X | X | O |
| transient | X | X | X |
| volatile | O | X | X |
5. Métodos con argumentos variables
Los argumentos variables son una de las nuevas características de JSE5.0, e indican que cierto argumento puede recibir un número indeterminado de valores. Solo puede existir un argumento variable para un método y debe ser el último declarado:
void hacerCosas(int otroArgumento, String... valores){}
6. Declaración de constructores
Un constructor válido debe declararse como un método sin tipo de dato de retorno, con el mismo nombre de la clase, puede tener cualquier un modificador de acceso y no puede ser static, final o abstract (ninguno de los tres tiene sentido para un constructor).
public class Perro(){
//constructores válidos
Perro(){}
public Perro(){}
protected Perro(int valor){}
//private se suele usar para las clases singleton
private Perro(String ... args){}
}
7. Declaración de variables
Primitivas. Pueden ser de 8 tipos: char, boolean, byte, short, int, long, double o float.
Se pueden declarar varias al mismo tiempo e inicializarlas:
int a, b, c, d = 9;
short uno = 1, dos = 2, tres = 3;
Para las versiones anteriores del examen había que conocer los tamaños en bits o bytes de los tipos de datos, para esta versión solo es necesario saber que el orden ascendente de los tipos enteros es: byte, short, int y long; y que float es más pequeño que double.
De Referencia. Se declaran igual que las primitivas pero estas apuntan hacia objetos.
String a = "HOLA", b = null, c = new String("Otro Hola");
8. Variables de instancia
Son las que se declaran afuera de los métodos y existe una por cada instancia de la clase. Pueden modificarse con cualquiera de los cuatro niveles de acceso y usar los siguientes modificadores: final, transient y volatile. No pueden ser ni synchronized, strictfp, native ni static (con esto dejarían de ser variables de instancia).
9. Variables locales
Las variables locales o automáticas, son las que se declaran dentro de los métodos. Solo pueden usar el modificador final, para ellas no aplican los modificadores de acceso. Deben ser inicializadas antes de usarlas:
void hacerAlgoBienBacano(){
int valor; //variable local
System.out.println("valor = " + valor); //Error de compilación!!!
}
10. Declaración de arreglos
Se declaran de forma similar a cualquier dato primitivo o de referencia, pero se incluyen brackets a la derecha del tipo de dato o del nombre de la variable para indicar el número de dimensiones del arreglo.
String array[][]; //arreglo de Strings de dos dimensiones
int[] arr1, arr2[]; //arr1 es de una dimensión, pero arr2 es bidimensional
11. Variables y métodos static
El modificador static se usa para crear variables que existirán de forma independiente de cualquier instancia de la clase a la que pertenecen. El modificador static aplica para métodos, variables, clases internas y bloques de inicialización.
El modificador no aplica para constructores, clases, interfaces métodos de clases internas locales, variables de instancia (por que dejarían de ser de instancia) y variables locales.
12. Declaración de enums
Son otra de las nuevas características en JSE5.0. Se crearon para hacer un uso más seguro de las constantes, pues anteriormente se debían declarar como tipos de datos del lenguaje (generalmente primitivos), por lo que las variables podían tener cualquier valor de el dominio del tipo.
Con esta nueva característica es posible restringir el número de valores que puede tener una variable a un grupo de datos predefinido.
enum Animales{PERRO, GATO, MARRANITO, POLLITO};
Animales miMascota;
Con esta simple declaración la variable miMascota solo podrá tener valores que estén declarados detro del enum Animales.
Los enums se comportan de forma muy similar a las clases, es decir, solo pueden usar los modificadores de acceso por defecto (cuando no se digita nada) y public, cuando son públicos el nombre del enum debe ser el mismo del archivo que lo contiene. También pueden declararse dentro de clases (como las clases internas) e interactuar con los modificadores public, private, protected, static y strictfp. No pueden llevar los modificadores transient, volatile, synchronized ni abstract.
Los enums pueden tener constructores, variables de instancia, métodos y 'constant specific class body' (no me atrevo a traducirlo!). Todo se entiende mejor con un ejemplo.
enum TipoPollo {
//cada tipo de preparación tiene un número de calorias
CRUDO (10), ASADO (40), COCINADO (20), FRITO (100);
private int calorias;
//los valores que se pasan como argumento a la declaración
//de la variable, son pasados al constructor
TipoPollo(int calorias){
this.calorias = calorias;
}
public int getCalorias(){
return this.calorias;
}
public String getPresa(){
return "MUSLO";
}
}
Dada la anterior lista enumerada, podemos invocarla desde otra clase y ejecutar el siguiente método main():
public static void main(String[] args) {
TipoPollo unaPresa = TipoPollo.CRUDO;
System.out.println("El pollo está " + unaPresa.name());
System.out.println("El número de calorías es: " + unaPresa.getCalorias());
System.out.println("La presa que venden es: " + unaPresa.getPresa());
}
Ahora supongamos que el pollo frito viene en alas, el resto en muslos; se podría hacer empezar a preguntar por el tipo de presa (if (this.equals(FRITO)) return "ALA"; else return "MUSLO";)) o sobreescribir el método getPresa() del valor FRITO:
enum TipoPollo {
//cada tipo de preparación tiene un número de calorias
CRUDO (10), ASADO (40), COCINADO (20),
FRITO (100){
@Override
public String getPresa(){
return "ALA";
}
};
private int calorias;
//los valores que se pasan como argumento a la declaración
//de la variable, son pasados al constructor
TipoPollo(int calorias){
this.calorias = calorias;
}
public int getCalorias(){
return this.calorias;
}
public String getPresa(){
return "MUSLO";
}
}
Así, al ejecutar el método main():
public static void main(String[] args) {
TipoPollo unaPresa = TipoPollo.FRITO;
System.out.println("El pollo está " + unaPresa.name());
System.out.println("El número de calorías es: " + unaPresa.getCalorias());
System.out.println("La presa que venden es: " + unaPresa.getPresa());
}
La salida sería:
El pollo está FRITO
El número de calorías es: 100
La presa que venden es: ALA
Algunas conclusiones:
- Los constructores de los enums no pueden ser invocados directamente.
- Se puede definir más de un argumento para el constructor (aunque esto no se concluye del código que puse de ejemplo :-]).
- Las constantes pueden sobreescribir los métodos de la lista enumerada.
El Final
Hasta acá el final del primer capítulo del libro guía, es bueno practicar bastante esta primera parte por que es la base para el resto de capítulos, hay muchas preguntas llenas de marañas y procesos complejos cuya respuesta será un simple "compilation fails" y se identificará fácilmente si se tienen claros estos conceptos.
En sprogramando monté un listado de preguntas sobre el capítulo que pueden servir para evaluar el conocimiento sobre el tema, así que a practicar, la url es: http://sprogramando.wikidot.com/scjp-for-jse5-preguntas-grupo1.
Si hay errores en este texto, los anteriores o las preguntas, por favor escribirlo en los comentarios.
Un saludo.
Posted at 11:00PM may 28, 2007 by Carlos Alexander Zuluaga in Java | Comentarios[4]


Bien hecho, gracias por la info, solo un comentaio, por favor quita el color verde de los comentarios, molesta a los ojos, gracias
Enviado por luis en junio 05, 2007 a las 04:37 PM COT #
Hecho, gracias por la sugerencia.
Enviado por azuluaga en junio 05, 2007 a las 10:24 PM COT #
Buen trabajo. Estoy siguiendo tu blog como ayuda.
En el punto 3 (Otros modificadores), indicas que abstract sólo aplica a los métodos. Intuyo que te referías a que no aplica a las variables, pero entonces strictfp también debería aplicar sólo a los métodos.
Todo sea porqué todos aprobemos!
Saludos.
Enviado por XerXi en junio 14, 2007 a las 10:39 AM COT #
Gracias XerXi por la corrección, tenías razón, lo correcto es decir que abstract aplica para clases y métodos. Corrección hecha.
Un saludo.
Enviado por azuluaga en junio 20, 2007 a las 03:00 PM COT #