Pasando variables a métodos:

Los métodos pueden ser declarados para tomar primitivas y/o referencias a objetos. Necesitamos saber como (o si) la variable del que llama al método va a ser afectada por el método. La diferencia entre una referencia a un objeto y una variable primitiva cuando es pasada a un método es grande e importante.

  • Pasando variables de referencia a objetos:
    Cuando pasamos una variable de tipo objeto a un método, debemos saber que estamos pasando la referencia al objeto y no el objeto en si mismo. Recordemos que las variables de referencias contienen un patrón de bits que representa una manera de encontrar a un objeto en memoria (en el Heap mas precisamente). Mas importante aun es que no pasamos la variable de referencia actual, sino una copia de la variable de referencia.
    En otras palabras, el que invoca y el método ahora tienen idénticas copias de la referencia, y los dos se refieren exactamente al mismo (no una copia) objeto en el Heap.
  • Java usa la semántica de pasaje por valor?
    Si java pasa objetos pasando la referencia, esto significa que java usa pasaje por referencia? No exactamente, a pesar de esto, seguido van a escuchar que lo hace. Java realmente realiza pasaje por valor para todas las variable corriendo sobre la misma Virtual Machine. Pasaje por valor significa pasaje por el valor de la variable. Y esto se traduce a pasaje por copia de la variable.
    No hay diferencia si estamos pasando variables primitivas o de referencia, siempre estamos pasando una copia de los bits de la variable.
    Y para la referencia a objetos pasamos una copia de los bits que representan la forma de encontrar a un objeto. Pero estas referencias iguales apuntan al mismo objeto, y si el método modifica al objeto, el que invoco al método vera el objeto cambiado.
    Recordar: El método no puede cambiar la variable del que realizo la invocación. Es decir, que el método no puede re-asignar la variable de referencia que pertenece al que invoco al método para que se refiera a otro objeto o a null.
  • Pasando variables de tipo primitivas:
    Se pasa copiando los bits que representan al valor que contiene la variable.

Declaración, construcción e inicialización de Arrays:

Los arrays en java son objetos que guardan múltiples variables del mismo tipo. Pueden contener tanto primitivas como referencias a objetos, pero el array en si siempre va a ser un objeto en el Heap, aunque haya sido declarado para contener primitivas.

  • Declarando Arrays

    • De primitivas: int[] keys;
    • De referencias a objetos: Thread[] threads;
      Es ilegal si ponemos el tamaño en la declaración: int[5] scores; //No compila
  • Construyendo Arrays
    Significa crear objetos de tipo Array en el Heap. Para crear este objeto Java debe saber cuanto espacio reservar en el Heap, eso debemos especificar el tamaño del array a la hora de crearlo. El tamaño es la cantidad de elementos que el array podría contener.
  • Construyendo arrays de una dimension:
    int[] testscores;
    testscores = new int[4];
    El codigo anterior pone un nuevo objeto en el heap (un objeto tipo array conteniendo 4 elementos) donde cada elemento contiene un int con el valor por defecto (cero en este caso).

    (Copiar figura pag 211)

    Ej: un array de referencia a objeto: Thread[] t=new Thread[5];
    Hay que tener en cuenta que a pesar de que pueda parecer que se esta llamando al constructor de la clase Thread, esto no pasa. hasta aca no se ha creado ninguna instancia de Thread.

  • Construyendo arrays multidimensionales:
    Son solo arrays de arrays.
    int [][] myArray= new int[3][];
    Hay que notar que el codigo anterior es legal ya que la JVM necesita saber solo el tamaño del objeto asignado a la variable myArray.

    (Copiar figura pag 213)

  • Inicializando un array:
    Significa poner cosas dentro del array.
    Animal[] pets= new Animal[3];
    pets[0]=new Animal();
    pets[1]=new Animal();
    pets[2]=new Animal();
  • Declarando, construyendo e inicializando en una solo linea:
    Ej: int[] dots={2,4,8}; donde el tamaño del array se obtiene por la cantidad de elementos separados por coma.
    Ej: Dog[] myDogs={new Dog(“1″),new Dog(“2″)};
    Ej: int[][] scores= {{1,2},{3,4},{5,6,7,8}};

Otros modificadores (no de acceso):

  • Clases Final: cuando marcamos una clase con el modificador final, la clase no puede ser heredada. Solo utilizariamos final para garantizar un comportamiento en una clase y por razones de seguridad.
  • Clases Abstractas: Una clase abstracta nunca puede ser instanciada, su unica razon en la vida es ser extendida. Solo estan para aprovechar las abstracciones del pensamiento y reutilizar logica comun entre clases.
    Los metodos abstractos terminan con ; y no con {}. Si hay un solo metodo abstracto en la clas, la clase entera debe marcarse como abstracta.
    Codificar clases de tipo abstracta nos permite tomar ventaja del polimorfismo y nos da gran flexibilidad y extensibilidad.
    Si usamos abstract y final no compila, ya que los modificadores tienen sentidos opuestos.

Declaracion de Interfaces:

Cuando creamos una interfaz, estamos definiendo un contrato de lo que una clase puede hacer, sin decir como lo hara la clase.

Las interfaces puede ser implementadas por cualquier clase en cualquier nivel del arbol de herencia, lo que nos tener clases muy distintas con algunas caracteristicas iguales.

Tenemos que pensar en una interfaz como una clase 100% abstracta. Donde solo puede haber metodos abstractos.

Las interfaces tienen menos flexibilidad en las declaracionesÑ

  • Todos los metodos son public y abstract y terminan con ;
  • Todas las variables definidas deben ser publi, static y final, en otras palabras constantes.
  • Los metodos no pueden ser static.
  • Como los metodos son abstractos no se pueden marcar con fina, strictfp o native.
  • Una interfaz puede extender una o mas interfaces.
  • Una interfaz solo puede extender interfaces.
  • Una interfaz no puede implementar otra interfaz o clase.
  • Una interfaz debe ser marcada con la palabra clave interface.

Declarando constantes en las interfaces:

Tienen que ser public, static y final, pero no hace falta que lo aclaremos. Y aunque no lo alcaremos debemos recordar que son constantes y no se les puede modificar el valor.

Declarando miembros de clase: (miembro = metodos y variables de instancia) :

  • Modificadores de acceso:(se usan los 4)
    Que significa que una clase tenga acceso a un miembro de otra clase? visibilidad como antes.
    Pero hay que entender 2 tipos de acceso:

    • Cuando un miembro de una clase trata de acceder a un miembro de otra clase
    • Cuando una subclase hereda un miembro de una super clase.

    El primer tipo es cuando desde una clase con el operador (.) accedemos a una variable o a un metodo de otra clase. Y el segundo tipo es cuando una subclase puede acceder a sus miembros heredados.

  • Miembros publicos:
    Si es publico, cualquier clase sin importar el paquete puede acceder al miembro
  • Miembros privados:
    Si es privado, no puede ser accedido por ningun codigo fuera de la clase donde se declaro. Tampoco se herada en el caso de ser extendida la clase.
  • Miembros protected y default:
    Estos dos modificadores son muy parecidos, salvo por una gran diferencia. Un miembro declarado como default solo puede ser accedido si la clase que esta tratando de accederlo esta en el mismo paquete.
    Cuando si es marcado como protected puede ser accedido (mediante la herencia) por una subclase aunque este en una clase en otro paquete.
    Entonces podemos concluir que el modificador protected es solo visible para una subclase.Cuando pensamos en default, pensamos en restriccion de paquete y cuando pensamos en protected pensamos en paquete + hijos.
    Esto no significa que la subclase va a poder usar el operador (.) sobre el miembro en la super clase, sino que lo va a poder acceder porque lo heredo.
    Cuando un miembro protected se hereda en una clase fuera del paquete, el miembro se vuelve privado en la subclase. Por lo tanto la sub clases de la subclase no lo heredan.
    En cambio si un miembro es puesto como default la herencia del mismo se realiza si la subclase esta en el mismo paquete que la super clase.

Variables locales y modificadores de acceso:

Nunca se aplican modificadores a variables locales!!! El unico modificador que se aplica es final.

Tabla de comparacion de modificadores:

(Insertar grafico)

Modificadores de miembros no de acceso:

  • Metodos final:
    Final previene a un metodo ser sobre escrito en una subclase, y por lo general se usa para asegurar la funcionalidad de una API.
  • Argumentos final:
    Los argumentos son las variables que se declaran entre los parentesis de la definicion de un metodo. Y cuando le agregamos el modificador final los valores no puede ser modificado dentro del metodo.
  • Metodos abstractos:
    Son metodos que son declarados pero no son implementados. Por eso terminan con (;) y no con ({}) y no tienen cuerpo.
    Cabe aclarar que podemos tener una clase abstracta que no tenga ningun metodo abstracto.
    La primer subclase concreta (es decir, que no sea abstracta) debera implementar todos los metodos abstractos de la super clase.
    Un metodo nunca puede ser declarado como abstract final, ni como abstract private.
    Y nunca podemos usar abstract static.
  • Metodos synchronized:
    Indica que el metodo puede ser accedido por un solo hilo a la vez. Synchronized solo se aplica a metodos y se puede combinar con cualquiera de los 4 modificadores de acceso.
  • Metodos native:
    Indica que el metodo es implementado en codigo dependiente de la plataforma, por lo general en C. Y el modificador native solo se aplica a metodos, los cuales no tiene cuerpo y por esto temirnan con (;).
  • Metodos strictfp:
    Strictfp fuerza a que los puntos flotantes cumplan con el estandar IEEE 754.
  • Metodos con argumento variable(var-args):
    Desde java 5.0 podemos tomar un numero variable de argumentos.
    Diferencia entre argumento y parametros:

    • Argumento: lo que especificamos entre los parentesis cuando invocamos a un metodo.
    • Parametros: lo que definimos en la firma (o signature) de un metodo.

    Algunas reglas importantes:

    • El argumento var-args puede ser de cualquier tipo
    • La sintaxis es la siguientes: void doStuff(int… x)

Declaracion de constructores:

En Java los objetos son contruidos. Por lo tanto cuando creamos un objeto(con la palabra clave new), al menos un constructor es llamado.

Reglas:

  • Nunca debe especificar un return type
  • Puede tener cualquier modificador
  • Puede recibir var-args
  • Tienen que tener el mismo nombre que la clase
  • No puede ser marcado como static, final o abstract.

Declaracion de variables:

Hay 2 tipos de variables en Java:

  • Primitivas:
    Alguno de los 8 tipos: char, boolean, byte, short, int, long, double, float. Una vez que se declararon su tipo no puede cambiar. Su valor si.
  • Variables de referencia:
    Son usadas para acceder o referirse a un objeto. Una variable puede hacer referencia a cualquier objeto del tipo que se declaro o a cualquier subclase del tipo que se declaro.

Declarando primitivas y rangos de primitivas:

Todas las primitivas numericas son signed.

  • byte – 8 bits
  • short – 16 bits
  • int – 32 bits
  • long – 64 bits
  • float – 32 bits
  • double 64 bits

Los rangos se calculan con:

  • Negativo: -2^(bits-1)
  • Positivo: 2^(bits-1)-1, ya que el cero se guarda como binario positivo.

Variables de instancia:

Son definidas dentro de la clase y fuera de todos los metodos. Son campos que pertenecen a cada objeto que se instancia.

Variables locales(Automatic/Stack/Method):

Las variables locales son declaradas dentro de los metodos. La variable se declara y se destruye cuando el metodo finaliza. Las variables locales se almacenan en el Stack no en el Heap. Aunque la variable este en el Stack si es una variable de referencia a un objeto, el objeto igual esta en el Heap, por lo tanto no existen los Stack Objects, solo las Stack variables. Por lo tanto cuando hablemos de Local Object es sinonimo de variable declarada localmente de referencia.

Una cosa que hay que recordar es que, las variables locales deben ser inicializadas antes de ser usadas. Ya que a diferencia de las variables de instancia a las variables locales no se le asignan valores por defecto.

Es legal declarar una variable local con el mismo nombre que una variable de instancia, se conoce como shadowing.

Declaracion de Arrays:

En Java los Arrays son objetos que contienen multiples variables del mismo tipo. o variables que son de subclases del mismo tipo. Los arrays pueden tener tipos primitivos o referencias a objetos, pero el array en si siempre va a ser un objeto en el Heap, hasta si el array es declarado que contiene tipos primitivos.
Necesitamos saber tres cosas:

  • Como hacer una variable de referencia a un array (declaracion)
  • Como hacer un objeto array (construccion)
  • Como popular un array con elementos (inicializacion)

Final Variables:

Declarar una variable con el modificador final hace imposible reinicializar la variable una vez que fue inicializara con un valor explicito. Se entiende bien el concepto con variables primitivas, pero que pasa con una referencia a un objeto que es marcada con final? Lo que sucede es que la referencia nunca puede cambiar a otro objeto una vez que se inicializo. La informacion dentro del objeto puede cambiar pero no su referencia.

Variables Transient:

Cuando marcamos una variable con el modificador transient, le estamos diciendo a la JVM que ignore a esta variable que se intente serializar la clase. Solo se aplica a variables de instancia.

Variables Volatiles:

El modificador volatile le indica a la JVM que un hilo accediendo a la variable debe siempre conseguir su propia copia privada de la variable en memoria. Solo se aplica a variables de instancia.
Variables y Metodos Static:

El modificador static es usado para crear variables y metodos que existiran independientemente de que alguna intancia de la clase exista. Cosas que se pueden marcar como estaticas:

  • Metodos
  • Variables
  • Una clase incluida en otra
  • Bloques de inicializacion

Declarando Enums:

Desde Java 5.0 podemos restringir el valor de una variable a unos pocos valores predefinido, es decir, un valor de una lsta enumerada. Los items dentro de la lista se llaman enums.

Con una simple declaracion, garantizamos que el compilador se va a quejar si tratamos de asignar algun otro valor que no este en la lista.

Ej: enum CoffeeSize { BIG, HUGE, OVERWHELMING } ; con el punto y coma final opcional en este caso.

Luego hacemos CoffeeSize cs= CoffeeSize.BIG;

Los enums pueden ser declarados como una clase separada o como un miembro de una clase, pero no pueden ser declarados dentro de un metodo.

Declarando constructores y variables en un enum:

A los enums podemos agregarles constructores, variables de instancia, metodos y algo muy extranio llamado constant specefic class body.

EJ:

(IMAGEN)

Punto a recordar sobre los constructores en los enums:

  • Nunca se puede invocar el constructor de un enum directamente
  • Se puede definir mas de un argumento en el constructor

Finalmente lo mas loco de los enums, es que podemos definir como una inner class anonima dentro del enum. Se conoce como constant specific class body, y es usada cuando necesitamos que una constante particular sobre escriba un metodo en en enum.

EJ:

(IMAGEN)

(SCJP)Sun Certified Java Programmer

Para comenzar algunas definiciones:

  • Clase: una plantilla que describe que tipos de estados y comportamientos pueden tener los objetos de un tipo determinado.
  • Objeto: en runtime, cuando la JVM encuentra la palabra clave “new” usa la clase indicada para crear un objeto que es instancia de esa clase.
  • Estado: son los valores de las variables de instancia
  • Comportamiento: es el codigo escrito dentro de los metodos, o los metodos en si mismo.. como lo quieran ver.

Identificadores y Palabras claves:

Todos los nombres (de clases, variables y metodos) son llamados identificadores. Sun tiene sus convenciones. Trambien java tiene un set de palabras claves que no pueden ser identificadores.

Herencia:

Este concepto permite que el codigo definido en una clase pueda ser rehusado en otra clase. Es uno de los conceptos principales en la OO y el lenguaje Java.

Interfaces:

Son como clases 100% abstractas que definien metodos que las subclases deben soportar, pero no definin comportamiento.

Identificadores y JavaBeans:

  • Identificadores legales: son las reglas del compilador que se usan para saber si un identificador esta bien escrito.
    Tecnicamente los identificadores deben estar compuestos solo por caracteres unicode, numeros, el simbolo $ y _ (underscore).
  • Reglas importantes:
    • Los identificadores deben empezar con una letra, $ o _, nunca con un numero
    • Luego del primer caracter puede seguir cualquier combinacion de los otros
    • No hay limite en la cantidad de caracteres de un identificador
    • Son case sensitive
    • No se pueden usar las palabras claves como identificadores

Reglas para la declaracion de archivos fuente:

  • Puede haber solo una clase publica por archivo
  • SI hay una clase publica en el archivo, el nombre del archivo debe coinsidir con el nombre de la clase publica
  • Si la clase es parte de un paquete, la sentencia package debe ser la primer linea del archivo
  • Los imports se declaran entre el package y la definicion de la clase
  • Un archivo puede tener mas de una clase no publica
  • Si no hay clase publica el nombre del archivo puede no coincidir con nada

Declaraciones de clases y modificadores:

MyClass.java:

class MyClass{ }

A esto se le puede agregar modificadores, los cuales se dividen en 2 categorias:

  • Modificadores de Acceso: public, protected, private, (default)
  • Otros modificadores: strictfp, final, abstract…

Vamos a empezar con los de acceso:

A una clase se le aplican public o default, los otros no tienen sentido. (y el private?)

Acceso a una clase:

Cuando decimos que una clase A tiene acceso a una clase B significa que A puede hacer 3 cosas:

  • Crear una instancia de B
  • Extender a la clase B
  • Acceder a ciertos metodos o variables de B. Segun el acceso que estos metodos y variables tengan.

Entonces podemos decir que acceso = visibilidad

Acceso Default:

Es cuando no especificamos ningun modificador. Podemos pensar a Default como Acceso a nivel de paquete. Ej: si dos clases estan en distintos paquetes y un de ella tiene acceso default, la otra no la va a poder ni ver. (es decir, usarla o hacer referencia a ella en ningun sentido)

Acceso Publico:

Con del modificador de acceso public hacemos una clase visible en todo el Universo Java (JU). Recordemos que si tratamos de usar una clase fuera del paquete igual tenemos que utilizar la sentencia import.