Declaración de Variables en Java

Buenas tardes, en esta entrada veremos lo mas importante referente a la declaración de variables.


Existen 2 tipos de variables en Java:

  • Primitivas:

    Puede ser cualquiera de los 8 tipos: char, boolean, byte, short, int, long, double o float. Una vez que un primitivo ha sido declarado, el tipo primitivo no puede cambiar nunca, sin embargo su valor sí.

  • Variables de Referencia:

    Una variable de referencia es usada para referenciar (o acceder) a un objeto. Una variable de referencia es declarada para ser un tipo específico y el tipo no puede ser nunca cambiado. Una variable de referencia puede ser usado para referir a cualquier objeto del tipo declarado, o a un subtipo del tipo declarado (un tipo compatible).

  • Declarando Primitivos y Rangos Primitivos

    Las variables primitivas pueden ser declaradas como variables de clase (static), variables de instancia, parámetros de métodos, o variables locales. Vamos a ver un ejemplo de estas declaraciones:

    				byte b;
    				boolean myBooleanPrimitive;
    				int x, y, z; 	//Declara 3 enteros primitivos
    				

    Para los tipos enteros la secuencia desde mas pequeños hasta mas grandes es byte, short, int y long, y double es mas grande que float. Ambos, enteros como tipos de puntos flotantes tienen signo, y esto afecta a sus rangos. Primero vamos a echar un vistazo a los conceptos.

    Cualquier tipo de número en Java están hechos con un número concreto de 8-bit bytes, y tienen signo, lo que quiere decir que pueden ser negativo o positivos. El bit que está a la izquierda es usado para representar el signo, donde un 0 significa negativo y un 1 significa positivo. El resto de bits representa el valor, usando 2 notaciones complementarias.

    -1

    Tipo Bits Bytes Rango Mínimo Rango Máximo
    byte 8 1 -27 27
    short 16 2 -215 215-1
    int 32 4 -231 231-1
    long 64 8 -263 263-1
    float 32 4 n/a n/a
    double 64 8 n/a n/a

    Para los tipos boolean no hay rango; un boolean solo puede ser true o false.

    El tipo char contiene un caracter singular de 16-bit Unicode.Aunque el ASCII extendido conocido como ISO Latin-1 necesita solo 8 bits(256 caracteres diferentes), se necesita un rango mayor para representar caracteres que se encuentren en otras lenguas diferentes al Inglés.

  • Declarando Variables de Referencia

    Las variables de referencia pueden ser declaradas como variables estáticas, variables de instancia, parametros de métodos, o como variables locales. Podemos declarar una o mas variables de referencia, del mismo tipo, en una misma linea. Ahora vamos a ver un ejemplo de este tipo de variables:

    				Object o;
    				Dog myNewDogReferenceVariable;
    				String s1, s2, s3; 	//Declara 3 variables de tipo String
    				
  • Variables de Instancia

    Las variables de instancia son definidas dentro de la clase, pero fuera de cualquier método, y son solo inicializadas cuando la clase es instanciada. Las variables de instancia son los campos que pertenecen a cada objeto único. Por ejemplo vamos a ver un objeto Employee:

    				class Employee{
    					//define los campos (variables de instancia) para el Empleado
    					private String name;
    					private String title;
    					private String manager;
    					//Otro código iría aqui
                         }
    				

    La clase Employee dice que de cada isntancia de Empleado se sabrá su nombre, el titulo, y el manager. Cada instancia puede tener su propios valores únicos para sus 3 campos. “field”, “variables de instancia”, “propiedades”, “atributos”, todo esto virtualmente se refiere a lo mismo.

    Hay que tener en cuenta varias cosas sobre las variables de isntancia:

    • Pueden usar cualquiera de los 4 niveles de acceso.
    • Pueden ser marcados como final.
    • Pueden ser marcados como transient.
    • No pueden ser marcados como abstract.
    • No pueden ser marcados como synchronized.
    • No pueden ser marcados como strictfp.
    • No pueden ser marcados como native.
    • No pueden ser marcados como static, porque entonces se convertirían en variables de la clase.

    Esta tabla puede ayudarnos un poco a recordar:

    Variables Locales Variables (no locales) Métodos
    final final final
    public public
    protected protected
    private private
    static static
    transient
    volatile
    abstract
    synchronized
    strictfp
    native
  • Variables locales (Automaticas/Stack/Métodos)

    Las variables locales son declaradas dentro de un método. Esto significa que la variable no solo se inicializa dentro del método, sino que tambien se declara dentro del método. Al igual que empieza su vida en el método, tambien se destruye cuando el método se ha completado. Las variables locales siempre están en el stack, no en el heap. Aunque el valor de la variable pueda ser pasada dentro, por decirlo así, de otro método que guarde el valor en una variable de instancia, la variable porsí misma solo vive dentro del ámbito del método.

    La declaración de una variable local no puede usar la mayoría de los modificadores que pueden ser aplicados a las variables de instancia, como public, transient, volatile, abstract o static, pero como ay dijimos con anterioridad, pueden ser marcados como final. Antes de usar una variable local, esta debe ser inicializada con algún valor. Por ejemplo:

    					class TestServer{
    						public void logIn() {
    							int count = 10;
    						}
    					}
    					

    Típicamente, inicializaremos la variable local en una misma línea en la cual la declaremos, aunque podemos aun necesitar reinicializarla mas tarde en el método. La clave de todo esto es recordar que una variable local debe ser inicializada antes de que se intente usar, ya que las variables locales no tienen valores por defecto, al contrario que las variables de instancia.

    No puede ser referenciada en cualquier lugar del código fuera del método en el cual ha sido declarado. En el ejemplo anterior sería imposible referenciar la variable count en cualquier lugar de la clase excepto dentro del ámbito del método logIn(). A continuación vemos un ejemlo de código que es ilegal:

    {sourcecode language=”java”]
    class TestServer{
    public void logIn(){
    int count = 10;
    }
    public void doSomething(int i){
    count = i; //No compilará!, No se tiene acceso a count fuera del método logIn()
    }
    }
    [/sourcecode]

    Es posible declarar una variable local con el mismo nombre que una variable de instancia, a esto se le conoce como shadowing:

    					class TestServer{
    						int count = 9; //Se declara una variable de instancia llamada count
    						public void logIn(){
    							int count = 10; //Declara una variable local llamada count
    							System.out.println("La variable local count es " + count);
    						}
    						public void count(){
    							System.out.println("La variable de instancia es " + count);
    						}
    						public static void main (String[] args){
    							new TestServer().logIn();
    							new TestServer().count();
    						}
    					}
    					

    El anterior código generará una salida como la siguiente:

    					La variable local count es 10
    					La variable de instancia es 9
    					
  • Declaración de Arrays

    En Java, los arrays son objetos que almacenan multiples variables de un mismo tipo, o variables que son subclases del mismo tipo. Los arrays pueden mantener ya sean variables primitivas o referencias a objetos, pero por sí mismo siempre serán objetos localizados en el heap, aunque el array sea declarado para mantener elementos primitivos.

    Los arrays son declarados poniendo el tipo de dato de los elementos que guardará (Objetos o primitivos), seguido de corchetes cerrados y seguido por el identificados.

    • 							int[] key; //Corchetes antes del nombre (recomendado)int key[]; // Corchetes despues del nombre (legal pero menos legible)
      							
    • 							Thread[] threads; //Recomendado
      							Thread threads []; //Legal pero menos legible
      							

    También podemos declarar arrays multidimensionales, los cuales son al fin y al cabo arrays de arrays.

    						String[][][] occupantName;
    						String[] managerName [];
    						

    El primer ejemplo es un array tridimensional (un array de arrays de arrays) y el segundo es un array de dos dimensiones. En el segundo ejemplo tenemos unos corchetes antes del nombre de la variable y otro despues del nombre. Esto es legal para el compilador, pero tenemos que pensar de nuevo en que lo legal no significa que esté bien.

  • Variables Final

    Declarar una variable con la palabra clave final hace que sea imposible reinicializar la variable una vez que ha sido inicializada con un valor explícito. Para las variables primitivas, esto significa que una vez que se le ha asignado un valor, el valor no puede ser alterado. Esto es fácil hablando de las variables primitivas, pero ¿Qué pasa si tenemos una referencia a un objeto final? Una variable de referencia marcada como final no puede ser reasignada para referir a otro objeto diferente. La información dentro del objeto puede ser modificado, pero la variable de referencia no puede ser cambiara. En otras palabras, una referencia final aun permitirá modificar el estado del objeto al que refiere, pero no podemos modificar la variable de referencia para ahcer que se refiera a otro objeto diferente. Por tanto, tenemos que grabar esto en nuestra cabeza: No hay objetos final, solo referencias final.

  • Variables Transient

    Si marcamos una variable de instancia como transient, le estamos diciento a la JVM que ignore o se salte a esta variable cuando intentemos serializar el objeto que la contiene. La serialización es una de las características mas importantes de Java, ya que nos permite guardar/salvar un objeto escribiendo su estado en un tipo especial de I/O stream. Con la serialización podemos guardar un objeto en un archivo, o o mandarlo a otro lugar donde se deserializa en otro sitio, en otra JVM.

  • Variables volatile

    El modificador volatile le dice a la JVM que un hilo que acceda a la variable debe siempre reconciliar su propia copia privada de la variable con una copia maestra en memoria. Esto es solo aplicable a variables de instancia.

  • Métodos y Variables static

    El modificador static es usado para crear variables y métodos que existirán independientemente de cualquier instancia creada de la clase. Todos los miembros static existen antes de que se haga una nueva instancia de la clase, y siempre habrá una sola copia del miembro static sin tener en cuenta el numero de instancias de la clase. En otras palabras, todas las instancias de una clase dada comparten el mismo valor para una variable static dada.

    Cosas que podemos marcar como static:

    • Métodos.
    • Variables.
    • Una clase anidada dentro de otra clase, pero no dentro de un método.
    • Bloques de Inicialización.

    Cosas que no podemos marcar como static:

    • Constructores.
    • Clases (A no ser que estén anidadas).
    • Interfaces.
    • Métodos locales dentro de las clases.
    • Métodos internos de la clase y variables de instancia.
    • Variables locales.

Hasta aquí este largo tema en el que hemos visto algunos tipos de declaraciones, como deben hacerse y cosas a tener en cuenta a la hora de hacerlos.

Sin mas, cualqueir aporte o corrección es bienvenido.

Saludos!!!