SCJP – Fundamentos : SCJP – Fundamentos * Extraído desde: http://www.sun.com/training/catalog/courses/CX-310-055.xml
Fundamentos : Fundamentos Elementos de un archivo fuente
Declaración de paquete (única)
Instrucciones “import” (cero o mas)
Definiciones de clase (cero o mas, solo una publica –incluso si es interface- )
El nombre de la clase publica debe ser el mismo del archivo (y .java)
Sin embargo un archivo fuente puede no tener una clase publica, ó incluso nada.
La importación de paquetes no es recursiva (no importa sub paquetes)
Los comentarios pueden estar en cualquier lugar, pero no pueden ser anidados.
Identificadores : Identificadores Un identificador valido en Java comienza con una letra (unicode), “$” o “_”, después cualquier combinación de letras, “$”, “_” o dígitos
Los caracteres unicote pueden estar en cualquier parte del codigo fuente, las siguientes instrucciones son todas validas:
ch\u0061r a = 'a';
char \u0062 = 'b';
char c = '\u0063';
Todos los tipos de datos enteros son con signo excepto “char”
Arreglos : Arreglos Los arreglos son objetos y para crearlo hay que seguir estos pasos:
Declarados: int[] a; String b[]; Object []c; (no se especifica el tamaño)
Asignados o construidos: a = new int[10]; c = new String[arraysize] (el argumento “arraysize” es de tipo entero)
Inicializados: for (int i = 0; i < a.length; a[i++] = 0)
Lo anterior se puede hace en un solo paso:
int a[] = { 1, 2, 3 }; ó int a[] = new int[] { 1, 2, 3 }; (En ninguna caso se indica el tamaño, se determina a través del numero de elementos “literales”)
Arreglos : Arreglos El tamaño de un arreglo no puede ser cambiado
Arreglos “anónimos” pueden ser creados así: new int[] {1,2,3} ó new int[10]
El índice de un arreglo comienza con 0 y la cantidad de elementos se determina con el atributo length (el ultimo elemento es igual arreglo.length - 1).
Pueden ser creados arreglos con cero elementos
El “Garbage Collection” es un mecanismo a través del cual se recupera memoria desde objetos “sin uso”, aumentando la memoria disponible para nuevos objetos.
Recolección de Basura : Recolección de Basura Un objeto “sin uso” es aquel que no puede ser referenciado por ninguna parte “activa” del programa.
El “Garbage Collection” corre como un Thread de baja prioridad.
No es posible forzar el Garbage Collection, solo se puede “sugerir” su ejecución con System.gc()
No hay garantía sobre la recolección y ejecución de los “finalizadores” de los objeto. GC no se ejecutara si en la ejecución del programa no existen “garantías”.
Recolección de Basura : Recolección de Basura La memoria ocupada durante la ejecución del programa no será liberada hasta que el programa termine, a excepción de que el sistema operativo lo solicite.
Tampoco existen garantías con respecto al orden en que serán recolectados los objetos (elegibles por el GC)
Un objeto es elegible para la recolección de basura solo si las referencias desde otros objetos son a su vez también son elegibles para la recolección de basura.
Recolección de Basura : Recolección de Basura Referencias circulares no previenen que los objetos sean recolectados
Podemos asignar null a las variables de referencias y ejecutar gc para recolectar el objeto referenciado por la variable, pero si el objeto tiene asignado un Oyente (Listener), este no será recolectado, primero se debe remover el oyente.
Todos los objetos tienen un método “finalize”, el cual es heredado desde la clase Object
El método “finalize” : El método “finalize” El método “finalize” es utilizado para liberar recursos utilizados (posiblemente) por el objeto, el orden en cual es invocado este método no tiene relación con el orden de creación, la firma del método es:
protected void finalize() throws Throwable { }
El método finalize es ejecutado solo una vez por objeto, si se produce una excepción (en el método), el objeto continuara en estado “elegible”.
El método finalize puede ser ejecutado explícitamente pero esto no implica que será recolectado.
El método “finalize” : El método “finalize” El método finalize puede ser sobrecargado pero solo el método con la firma “original” será invocado por gc.
El método finalize no esta “encadenado” implícitamente, por lo que debe invocar al método finalize de la clase padre, pero el compilador no comprobara esto.
Se puede ejecutar System.runFinalization() puede ser usado para ejecutar (no debe ser ejecutado antes) los “finalizadores” de los objetos elegibles.
Operadores y Asignaciones : Operadores y Asignaciones Enteros
Los enteros dependiendo de la precisión se dividen en los siguientes tipos primarios:
byte 8 bits complemento a dos.
short 16 bits complemento a dos.
int 32 bits complemento a dos.
long 64 bits complemento a dos.
Enteros : Enteros Los enteros por defecto se almacenan internamente como tipo int, que es un valor de 32 bits con signo. Si fuese necesario que un literal se almacenara como long debe añadirse una letra l o L al final del literal. Estos pueden representarse en tres formatos diferentes:
decimal (no tiene notación especial)
octal (notación: prefijo 0)
hexadecimal (notación: prefijo 0x ó 0X)
Ejemplo; Decimal: 42, Hexadecimal: 0x2A, Octal: 052
Coma flotante : Coma flotante Los reales en coma flotante (números con parte entera y parte decimal), pueden ser de dos tipos: float y double.
Los primeros se almacenan en 32 bits y los segundos en 64 bits.
La diferencia esta dada por la capacidad de precisión, debido a la mayor cantidad de información que necesitan para representarlos.
Por defecto los literales de coma flotante se almacenan en double si fuese necesario expresar un literal como float solo basta poner una f ó F al final del literal.
Lógicos : Lógicos En Java el tipo lógico se ha implementado a través de los literales (y palabras reservadas): true y false.
Caracteres : Caracteres Los caracteres que se refieran a un único carácter unicode se representan entre comillas simples. Adicionalmente Java cuenta con un tipo de dato char (short) para almacenar este tipo de datos. También pueden incluirse caracteres no imprimibles como: \\, \, \b, \r, \f, \t, \n, \’, \”, \udddd, \ddd
Ejemplo de formatos de representación de enteros:
int i = 18;
int j = 022;//Version Octal: dos veces ocho mas dos
int k = 0x12;//Version Hex: una vez dieciséis mas dos
Precedencia y Asociatividad : Precedencia y Asociatividad
Operadores : Operadores Los operadores prefijos unarios y todos los operadores binarios (excepto el de asignación) son asociados de izquierda a derecha.
Todos los operadores unarios (excepto los prefijos), todos los operadores de asignación, y el operador condicional ternario (incluido el de creación de objetos y cast) son asociados de derecha a izquierda.
Las expresiones se analizan de izquierda a derecha, salvo que existan paréntesis.
Las reglas de precedencia determinan que operador debe ser aplicado primero entre dos operadores con diferente precedencia.
Ejemplo: Operadores : Ejemplo: Operadores ¿Como será evaluado: 2 + 3 * 4?
Será evaluado como 2 + (3 * 4), debido a que * tiene mayor precedencia que +.
Conversiones : Conversiones Java, es un lenguaje fuertemente tipificado, chequea en tiempo de compilación la compatibilidad de tipos.
Si un tipo puede ser sustituido por otro.
Pero a veces solo es posible hacerlo en tiempo de ejecución.
Un tipo de referencia (objeto) solo se encuentra construido en tiempo de ejecución.
Si un operador tiene operadores incompatibles (Por ejemplo, la asignación de un doble a un entero) Java demanda la utilización de un cast para indicar explícitamente el tipo de conversión.
Casting... : Casting... La sintaxis de cast, es la siguiente:
()
En tiempo de ejecución se creara un nuevo valor de que “mejor” represente al valor de .
El moldeo o casting puede ser aplicado a tipos primitivos como a referencias.
Obviamente el casting entre referencias y primitivos, no esta permitido.
Casting... : Casting... Los valores boolean no pueden ser “moldeados” a otro tipo, y viceversa.
Moldear a null genera un error de compilación ya que null no es un tipo.
Diferencia importante en la asignación:
Los tipos primitivos son chequeados en tiempo de compilación.
Los tipos de referencia son chequeados en tiempo de ejecución.
Las conversiones que involucran moldeos se llaman conversiones explicitas
Bajo ciertas condiciones el compilador realiza conversiones implícitas, por ejemplo cuando un char es asignado a un int
Estrechamiento y Ensanchamiento : Estrechamiento y Ensanchamiento Para un tipo de dato primitivo, un valor mas “estrecho” puede ser convertido a un valor mas “ancho” sin perder información.
Esto se conoce como “Conversión de ensanchamiento de primitivos”.
La conversión al próximo valor más “ancho” esta resumida en la siguiente figura. Las conversiones son transitivas.
Tabla de conversión : Tabla de conversión
Promociones Numéricas : Promociones Numéricas Los operadores numéricos solo permiten operandos de ciertos tipos. La promoción numérica es implícitamente aplicada a los operandos para convertirlos en tipos permisibles.
Existe una distinción importante entre la promoción numérica unaria y binaria.
Promoción Numérica Unaria : Promoción Numérica Unaria Si el operando del operador es menor a int, automáticamente será convertido a int.
En otras palabras los tipos byte, short, char son convertidos a enteros a través de una conversión de ensanchamiento de primitivos.
Asignar un resultado int a una variable de estos tipos requiere una conversión explicita.
Contextos de Aplicación : Contextos de Aplicación Operando de un operador aritmético unario como + y/o –
Operando de un operador de complemento (~)
Durante la creación de un arreglo, por ejemplo new int[20], donde la dimensión debe estar expresada en entero y por lo tanto debe ser evaluada
En el índice de un arreglo (Idem punto anterior)
Operandos individuales de los operadores shift <<, >> y >>>
Ejemplos: : Ejemplos: byte b = 3; // Asignación valida, literal “3” se encuentra en rango.
128 seria invalido.
b = (byte) –b; // Asignación valida, se requiere conversión explicita a byte ya que se produjo la promoción automática del operador unario -.
Promoción Numérica Binaria : Promoción Numérica Binaria La promoción numérica binaria implícita se aplica para lograr un apropiado ensanchamiento (primitivo) entre un par de operandos, siendo el de tipo mayor el mandatario para el ensanchamiento. Pero, siempre mayor a int.
byte, short, char, siempre son convertidos a int.
Contextos de Aplicación : Contextos de Aplicación La promoción numérica binaria es aplicada en los siguientes contextos:
Operandos de operadores aritméticos: *, /, %, + y –
Operandos de operadores relacionales: <, <=, > y >=
Operandos de operadores de igualdad numérica: == y !=
Operandos de operadores de bits (bitwise) &, ^ y |
Contextos de Conversión : Contextos de Conversión Las conversiones de tipo pueden ocurrir en los siguientes contextos:
Asignaciones, que involucren tipos de datos primitivos y referencias.
Invocaciones de métodos, que involucren parámetros de tipo primitivo y de tipo referencia
Evaluación aritmética de expresiones que involucren tipos numéricos
Concatenación de cadenas que involucren a objetos de la clase String y otros tipos de datos