1. Escribiendo Clases Java
    1. Una clase describe un objeto
    2. Objeto
      1. Puede representar algo tangible o algo menos obvio pero útil para el programa
      2. Es una instancia de una clase
    3. En un archivo .java solo puede existir una clase del tipo public de nivel superior
    4. Topic
      1. La clase Order no puede ser private ni protected porque no está permitido tener una clase de nivel superior de este tipo
      2. La clase Order no puede ser public porque la clase Customer ya es public. Por consiguiente, solo puede tener el acceso por defecto
    5. El nombre completo de una clase o interfaz cambia cuando se encuentra en un paquete. El nombre del paquete se convierte en un prefijo para el nombre de clase.
    6. El archivo bytecode compilado debe aparecer en una estructura de directorios en el sistema de archivo que coincida con el nombre del paquete.
  2. Paquetes
    1. Grupo de clases y/o interfaces
    2. Beneficios
      1. Organiza el programa por grupos de clases y/o interfaces que poseen cierta relación de usabilidad
      2. Crea un namespace a las clases e interfaces
    3. Palabra Resevada: package
      1. Coloca una clase e interfaces dentro de un paquete
      2. Debe estar en la primera línea del archivo fuente
    4. Unnamed Package
      1. Si una clase no específica un paquete, la clase pertenece al paquete unnamed
      2. Las clases del paquete unnamed NO pueden ser importadas dentro de un archivo fuente
    5. Palabra Reservada: import
      1. Permite hacer referencia a una clase sin necesidad de usar su nombre completo
      2. Se usa para importar una simple clase o todo un paquete (*)
      3. Las importaciones se realizan después de declarar el paquete y antes de declarar la clase
      4. El compilador de Java elimina todas las declaraciones de importación y sustituye a todos los nombres de clase en el código fuente con sus nombres completos.
      5. El paquete java.lang es el único que el compilador importa automáticamente
      6. Importar todo un paquete con el uso del comodín (*) no tiene impacto sobre el tamaño del archivo compilado (bytecode file). Esto se debe a que realmente no se incluye nada en el archivo fuente.
      7. El estándar de Java para el nombre de paquetes es utilizar el nombre de dominio de la empresa (en sentido inverso) como prefijo a los nombres de su paquete. Ej: net.kielsaenz
    6. Estructura de Directorios
      1. El uso de paquetes origina que el código compilado aparezca dentro de una estructura de directorio que es igual al nombre de su paquete
      2. Opción -d del compilador
        1. El código compilado se emitirá en el directorio especificado
        2. Crea dentro del directorio de salida una estructura de directorios adecuada que coincida con los nombres de paquetes de las clases
        3. java -d <directorio de salida> <clases a compilar>
    7. La variable de entorno CLASSPATH
      1. Especifica los directorios y archivos JAR en donde se desea que el compilador y la JVM busquen archivos compilados
      2. Puede contener cualquier número de directorios y archivos JAR
      3. Se debe hacer referencia al directorio padre. El compilador y el JRE buscará en los subdirectorios apropiados.
      4. ERROR COMÚN: Agregar parte del nombre del paquete
  3. Corriendo Aplicaciones Java
    1. El punto de entrada a un programa Java es el método main, que puede estar definido en cualquier clase: public static void main(String[] args)
    2. Comando java
      1. Se utiliza para ejecutar una aplicación: java nombre_aplicacion
      2. Asume que el archivo compilado se encuentra en el mismo directorio
      3. Para ejecutar la aplicación desde cualquier directorio, se debe incluir dicha aplicación en el CLASSPATH
      4. Solo se necesita el nombre de la clase, la cual debe contener el método main
      5. ERROR: java HelloWorld.class (la JVM buscará la clase class dentro del paquete HelloWorld)
      6. -classpath
        1. Permite especificar la ruta de clases a partir de la línea de comandos
        2. Garantizar que se esté apuntando a los directorios y archivos JAR correctos
        3. Reemplaza la variable de entorno CLASSPATH
        4. Ejemplo: java -classpath c:\myproject\build com.sybex.demos.TestColors
        5. Para separar multiples directorios usar
          1. Windows: punto y coma (;)
          2. Unix: coma (,)
        6. Se puede utilizar la abreviatura -cp en lugar de -classpath
    3. Archivos JAR
      1. Archivos de código de bytes (bytecode) se pueden almacenar en archivados comprimidos denominados archivos JAR
      2. El compilador y la JVM puede encontrar archivos de código de bytes en archivos JAR sin necesidad de descomprimir los archivos
      3. Ejemplo: C:\myproject\build > jar -cvf myproject.jar .
      4. La opción -c es para crear un nuevo archivo JAR
      5. La opción -v indica al comando jar ser prolijo mientras procesa los archivos (recursividad)
      6. La opción -f denota el nombre del archivo JAR, en el ejemplo es myproject.jar
      7. Después del nombre del archivo, se debe especificar los archivos o directorios a incluir en el JAR
    4. Argumentos
      1. Los argumentos en la línea de comandos se pasan al método principal como una sola matriz de objetos String
      2. Topic
  4. Tipos de Referencia vs Tipos Primitivos
    1. Tipos Primitivos
      1. Son ocho los tipos de datos primitivos y representan los bloques de construcción de objetos de Java
      2. Todos los objetos de Java son un conjunto complejo en memoria de estos tipos de datos primitivos
      3. Tipos de Datos Primitivos
        1. byte
          1. 8 bits
          2. -128 a 127
        2. short
          1. 16 bits
          2. -32768 a 32767
        3. int
          1. 32 bits
          2. -2147483648 a 2147483647
        4. long
          1. 64 bits
          2. -9223372036854775808 a 9223372036854775807
        5. float
          1. 32 bits
          2. 2^-149 a (2-2^-23).2^217
        6. double
          1. 64 bits
          2. 2^-1074 a (2-2^-52).2^1023
        7. char
          1. 16 bits
          2. '\u0000' a '\uffff' (0 a 65535) - Formato UNICODE
        8. boolean
          1. --
          2. verdarero o falso
      4. int x = 12345;
        1. Mantienen sus valores en la memoria donde se asigna la variable
        2. Un tipo primitivo sólo puede almacenar un valor de ese mismo tipo
    2. Tipos de Referencia
      1. Topic
        1. Son variables del tipo clase, interface o matriz
        2. No tienen el valor del objeto al que se refieren. En su lugar, almacenan la dirección de memoria donde se encuentra el objeto (puntero)
        3. El lenguaje Java no permite a un programador para acceder a una dirección de memoria física de ninguna manera
        4. sólo puede usar una referencia para acceder a los campos y métodos del objeto al que se refiere
      2. Literales de Cadena
        1. La palabra reservada new no es necesaria para crear el objeto String
        2. Los literales de cadena reciben un trato especial por la JVM
        3. La instancia un objeto String es almacenada en la piscina de cadenas
        4. Como los objetos String en Java son inmutables, la JVM puede optimizar el uso de literales de cadena, al permitir sólo una instancia de una cadena en la piscina
      3. Tipo null
        1. El tipo null no tiene un nombre, por lo que no es posible declarar una variable que debe ser el tipo nulo.
        2. Se puede asignar cualquier referencia al tipo null
        3. Los tipos primitivos no pueden ser asignados a null, solo referencias
      4. Dos referencias son compatibles sólo si los objetos que señalan son del mismo tipo o uno de los objetos es una hija de la otra.
  5. Recolector de basura (Garbage Collections)
    1. Objeto Inaccesible
      1. El objeto ya no tiene referencias apuntando hacia él
      2. Todas las referencias al objeto estan fuera de alcance (scope)
    2. Topic
      1. La referencia es una variable que tiene un nombre y puede ser utilizado para acceder al contenido de un objeto.
      2. Una referencia puede ser asignada a otro de referencia
      3. Todas las referencias son del mismo tamaño
      4. Una referencia usualmente tiene 32 bits, pero su tamaño real depende de la JVM
      5. Un objeto se encuentra en la pila (heap) y no tiene un nombre
      6. Se accede a un objeto únicamente a través de una referencia
      7. Los objetos consumen diferentes cantidades de memoria
      8. Un objeto no puede ser asignado a otro objeto
      9. Es el objeto del que se encarga el recolector de basura, no de su referencia.
      10. Referencia
      11. Objeto
    3. Método: System.gc
      1. Método estático que INTENTA ejecutar el recolector de basura
      2. Único método que se comunica con el recolector de basura
      3. Sugiere a la JVM gastar esfuerzo hacia el reciclaje de objetos no utilizados a fin de que la memoria que ocupan en la actualidad estén disponibles para su reutilización
    4. Método: finalize Object.finalize()
      1. Sólo puede ser llamado una vez en un objeto
      2. Sólo se llama por el recolector de basura
      3. Es llamado después de que el objeto es elegible para la recolección de basura, pero antes de que el objeto sea recogido en realidad
      4. Es invocado por el recolector de basura antes de que el objeto sea recogido
  6. Llamada por valor
    1. Una variable que es pasada dentro de un método es llamada argumento
    2. Java simplifica el concepto de paso de argumentos a los métodos, proporcionando sólo una forma de pasar argumentos: por valor
    3. Pasar argumentos por valor significa que una copia del argumento se pasa al método
    4. Si el argumento pasado a un método es un tipo primitivo, es imposible para el método alterar el valor original primitivo
    5. Si el argumento pasado a un método es un tipo de referencia, es imposible para el método modificar la referencia original. Sin embargo, el método puede cambiar el objeto
    6. Cuando se pasan argumentos a un método, es la referencia lo que se pasa, no el objeto
    7. Ejemplo: Resultado = Albert Einstein
      1. La única razón por la que first y last no cambian de valor es porque son objetos del tipo String y los objetos String son inmutables
    8. Cuando se termina de ejecutar un método, los parámetros y las variables locales son destruidos y ya no existen en la memoria del programa
    9. Al igual que con los argumentos de los métodos, la mayor tamaño de datos que puede devolver cualquier método es de 64 bits (un long o double)
  7. Operadores
    1. Operadores de Asignación
      1. Asignación Simple (1)
        1. =
        2. Almacena el resultado de la derecha en la variable de la derecha
        3. Sucede un error de compilación si el resultado de la derecha no se puede convertir en el tipo de dato de la izquierda
      2. Asignación Compuesta (11)
        1. +=, -=, *=, /=, %=, &= ^=, |=, <<=, >>=, >>>=
        2. Los operadores de asignación compuesta realizan el operador dado primero entre los lados izquierdo y derecho del operando, y entonces el resultado se almacena en la variable de la izquierda.
        3. A veces el operador compuesto puede salvarnos de la necesidad de castear un valor antes de la asignación
    2. Operadores Aritméticos
      1. Operadores de Adición
        1. Los operadores + y - se conocen como operadores aditivos
        2. Pueden ser evaluados en cualquiera de los tipos primitivos, excepto booleanos
        3. El operador + se puede aplicar a objetos String, que se traduce en la concatenación de cadenas
        4. Si los operandos son de tipos diferentes, el operando más pequeño es promovido al más grande
        5. Al asignar un tipo de datos más grande a una más pequeña, el compilador se queja de una posible pérdida de precisión.
        6. La JVM asegura que el orden de las operaciones se evalúen de izquierda a derecha cuando los operadores comparten la misma precedencia
      2. Operadores Multiplicativos
        1. Los operadores *, /,% y se conocen como los operadores multiplicativos
        2. Tienen una prioridad más alta que los operadores aditivos
        3. Sólo se puede realizar con los tipos primitivos, de lo contrario, se produce un error del compilador
        4. Promueve ambos operandos al tipo de dato del operando más grande
        5. Si ambos operandos son más pequeños que un int, ambos operandos se convierten a int s antes de la multiplicación se produce
      3. Operador Módulo
        1. También conocido como el operador de resto (%)
        2. Evalúa el resto de dos números cuando se dividen
      4. Operados de Incremento y Decremento
        1. Son los operadores ++ y --
        2. Se pueden aplicar a una expresión ya sea como prefijo o como sufijo
        3. Tienen el mayor nivel de prioridad de todos los operadores de Java
        4. Sólo se puede aplicar a operandos numéricos y el resultado es el mismo tipo de datos del operando
        5. Cuando el operador aparece después del operando, el incremento o decremento no se produce hasta después que el operando se utilice en la expresión actual
        6. Cuando el operador aparece delante del operando, el operando se incrementa o decrementa primero y luego el resultado se utiliza en la expresión actual
    3. Operadores Relacionales
      1. < (menor que), <= (menor o igual que), > (mayor que), >= (mayor o igual que)
      2. Los operadores de relación sólo se puedem utilizar en tipos numéricos primitivos
      3. El resultado de cada operador relacional es siempre un valor booleano
      4. Si los operandos no son el mismo tipo primitivo, el operando más pequeño se promueve al tipo del operando más grande antes que la comparación se realice
    4. Operador instanceof
      1. El operador instanceof compara una referencia contra una clase o interface
      2. Sintaxis: reference instanceof ClassOrInterfaceName
    5. Operadores bit a bit y Lógicos
      1. & (AND), ^ (OR exclusivo), | (OR inclusivo), && (AND condicional), || (OR condicional)
      2. &, ^ y | requiere que ambos operadores sean del tipo numérico primitivo o expresiones lógicas
      3. Para operar con los tipos numéricos, los operadores son bit a bit
      4. Los operadores && y || requieren que los dos operandos sean expresiones lógicas
      5. Los operadores bit a bit se evalúan sobre los tipos enteros (int)
      6. Tabla
        1. 00
          1. 0 & 0 = 0
          2. 0 ^ 0 = 0
          3. 0 | 0 = 0
        2. 01
          1. 0 & 0 = 0
          2. 0 ^ 1 = 1
          3. 0 | 1 = 1
        3. 10
          1. 1 & 0 = 0
          2. 1 ^ 0 = 1
          3. 1 | 0 = 1
        4. 11
          1. 1 & 1 = 1
          2. 1 ^ 1 = 0
          3. 1 | 1 = 1
    6. Operador Condicional
      1. También llamado como "operador ternario" , ya que es el único operador que tiene tres operandos
      2. Sintaxis: boolean_expression ? true_expression : false expression
      3. Los operandos segundo y tercero pueden ser expresiones que se evalúan como un valor o cualquier método que devuelva un valor
      4. Versión condensada de una sentencia if / else
    7. Operadores de Igualdad
      1. == (es igual a), != (no es igual a)
      2. Los dos operandos son tipos primitivos numéricos
      3. Los dos operandos son tipos booleanos
      4. Los dos operandos son tipos de referencias o tipos nulos (null)
      5. Retorna un valor booleano
      6. Si un operando es un tipo más grande, entonces el tipo más pequeño se promueve antes de la comparación
      7. Entre dos referencias, compara las referencias, no los objetos a los que apuntan. Dos referencias son iguales si y sólo si apuntan al mismo objeto (o ambos apuntan a null)
      8. Situaciones de Uso
  8. Iigualdad de Objetos
    1. La clase java.lang.Object contiene el método: public boolean equals (Object obj)
    2. La regla general es reemplazar el método equals en todas las clases para definir lo que significa que dos objetos son iguales
    3. La igualdad debe ser basado en la lógica de negocio de su aplicación
    4. Debido a que el método equals se define en la clase Object, se puede invocar dicho método en cualquier objeto y pasarle cualquier otro objeto
    5. La clase java.lang.Object contiene el método: public int hashCode()
    6. Los métodos hashCode y equals se relacionan en el sentido de que dos objetos que son iguales debería generar el mismo código hash