RSS

Archivos Mensuales: septiembre 2011

Asignaciones – Paso de Parámetros en Java

El paso de parámetros en Java se hace siempre por valor, ya se trate de un tipo primitivo o de un tipo de referencia, el método trabaja con una copia de la variable.

En el caso de una variable de tipo primitivo, si dentro del método se  modifica la variable, estamos modificando la copia y no la variable original.

En el caso de variables de referencia, si se modifica la variable dentro del método se está modificando una copia de la referencia y no la referencia original. Eso sí, al tener una copia de la referencia que apunta al mismo objeto, sí se puede cambiar el contenido de éste.

Veámoslo con un ejemplo:

class PasoParametros{

    public static void main(String[] args){

    //Para un entero comprobamos que se modifica la copia, despues vuelve a su valor orig.
        int entero = 100;
        System.out.println("Antes de modificar: " + entero);
        modificar(entero);
        System.out.println("Despues de modificar: " + entero);

    //Para un array de un entero, comprobamos que con la copia de la referencia
    //podemos cambiar su contenido.
        int[] array = new int[1];
        array[0] = 100;
        System.out.println("\nAntes de modificar: " + array[0]);
        modificarContenido(array);
        System.out.println("Despues de modificar: " + array[0]);

    //Para el mismo array de entero, comprobamos que no podemos modificar la referencia.
        System.out.println("\nAntes de modificar: " + array[0]);
        modificar(array);
        System.out.println("Despues de modificar: " + array[0]);

    }

    static void modificar(int e){
        e = 200;
        System.out.println("Dentro de modificar: " + e);
    }

    static void modificarContenido(int[] a){
        a[0] = 200;
        System.out.println("Dentro de modificarContenido: " + a[0]);
    }

    static void modificar (int[] a){
    //Creamos un nuevo array "b" y hacemos que "a" apunte a este nuevo array.
    //Funciona solo dentro del metodo, puesto que "a" aquí es una copia.
        int[] b = new int[1];
        b[0] = 300;
        a = b;
        System.out.println("Dentro de modificar: " + a[0]);
    }

}

Resultado de la ejecución:

 
Deja un comentario

Publicado por en 28 septiembre, 2011 en Estudio, Tema 3

 

Etiquetas: , , , , , ,

Asignaciones – Asignaciones, Widening, Cast

La operación de asignación nos sirve para dar valor a una variable.

La forma genérica de una asignación es la siguiente:
variable = valor;

Donde valor puede ser un literal, otra variable o una expresión.

El proceso de la asignación se realiza en dos fases. En primer lugar, se evalúa la parte derecha y se obtiene un valor. En segundo lugar, se asigna ese valor a la variable de la parte izquierda.

Literales

Ya comentamos que tenemos ocho tipos primitivos en Java: byte, short, int, long, float, double, char y boolean. Un literal es un valor concreto de un tipo.

Enteros
Se pueden representar utilizando una notación decimal, octal o hexadecimal.
15        formato decimal.
017      formato octal, el prefijo 0 indica un valor octal.
0xF     formato hexadecimal, el prefijo 0x indica un valor hexadecimal.

Un literal entero se considera por defecto de tipo int. Para indicar que queremos que sea de tipo long debemos acompañarlo de ‘l’ o ‘L’. Algunos literales enteros: 15, 320, 29999, 130000, 250L.

Reales
Un literal real se considera por defecto de tipo double. Para indicar que queremos que sea de tipo float debemos acompañarlo de ‘f’ o ‘F’. Algunos literales reales en coma flotante: 3.4, 1293.239, 150.23F.

Carácter
Un literal char se escribe entre comillas simples. Como son carácteres Unicode también se puede especificar el carácter en concreto por sus dígitos hexadecimales.
Algunos literales char: ‘b’, ‘z’, ‘\n’, ‘\t’, ‘\u003B’

Lógico
Los literales son false y true.


Expresiones

Es frecuente que nos encontremos expresiones en la que participan diferentes tipos de datos. Algunos tipos de datos pueden ser compatibles (enteros con caracteres p.e),  mientras que otros no (enteros con reales).

Los booleanos no son compatibles con ningún otro tipo de dato.

En las expresiones con datos enteros el resultado será al menos un int o el tipo del mayor operando de la expresión.

byte a = 10;
byte b = 20;
byte c  = (a + b) * 0.5; //El resultado de (a+b) * 0.5 es de tipo double.

En este caso el compilador generará un error, se necesita una conversión.
En Java las conversiones pueden ser implícitas o explícitas.

Conversión Implícita (Widening)

Se produce cuando los tipos son compatibles y Java realiza la conversión de forma automática.
Siempre es posible asignar un valor de un tipo más pequeño en una variable de un tipo mayor.

Grande = Pequeño; //OK

 long a = 100;  //100 al ser un literal entero, es de tipo int.

No hay problema en guardar este valor en una variable long. La conversión es automática.

Conversión Explícita (Cast)

Cuando los tipos son incompatibles o existe la posibilidad de perder información en una asignación, el compilador dará un error pidiendo que se confirme esa asignación con una conversión explícita.

Pequeño = Grande; //ERROR

int a = 100L; //ERROR 100L es un literal de tipo long y se quiere asignar a una variable int.
int a = (int) 100L; // OK

El compilador generará error. Como sabemos que en la asignación no hay peligro de perder información al
caber 100 perfectamente en un int, convertimos explícitamente.


Casos Posibles de Asignaciones

    • Asignación de Iguales: Se produce cuando el tipo del valor a asignar coincide con el tipo de la variable. En esta situación no hay ningún problema.
      char c = 'a';
      int entero = 100;
      int suma = entero + 25;
      double precio = 950.283;
      boolean indCerrado = false;
      

En estas asignaciones es necesario ningún tipo de conversión.

    • Conversión de ampliación (Widening): Ocurre cuando el tipo del valor a asignar es más pequeño que el tipo de la variable.
      //grande = pequeño;  //OK
      int a = 150;  //Declaramos un entero
      long var = a; //La variable a se puede asignar al long var, ya que vamos de pequeño a grande.
      double b = 15.3f * var;
      

Cualquier expresión entera siempre se podrá asignar a una variable double, ya que es el mayor tipo entero.

  • Conversión de reducción (Narrowing): Ocurre cuando el tipo del valor a asignar es más grande que el tipo de la variable. Es necesaria la conversión explícita.
    //pequeño = grande; //ERROR
    //pequeño = (pequeño) grande; //OK
    
    long grande = 5500L;
    int pequeño = (int) grande; //Es necesario hacer un casting a int.
    
    byte primero = 5;
    byte segundo = 20;
    byte suma = (byte) (primero + segundo); //La suma de dos bytes es un int, por lo tanto necesita
    //un casting a byte.
    
    • Excepción:
      Cuando el valor a asignar es una expresión onstante de tipo byte, short, char o int el
      compilador hace la conversión automáticamente. Esto se llama compile-time narrowing of constants:

      byte auto = 10; //OK, no hace falta hacer byte auto = (byte) 10;
      

      Si la variable a asignar es final y “cabe” en el destino no es necesario casting:

      final short prueba = 100;
      byte destino = prueba; //OK
      
      final short prueba = 300; //sobrepasa el valor posible para los byte.
      byte destino = prueba; //ERROR: possible loss of precision
      
    • Nota:
      Aunque tengamos un valor real que pueda caber en un “float” y lo queremos asignar a un
      double, siempre será necesario el sufijo o el casting:

      float f = 500.7; //ERROR
      float f = 500.7f; //OK
      float f = (float) 500.7; //OK
      
  • Conversión de Tipos de Referencia:Se puede asignar a un tipo menos especializado un tipo más especializado en la jerarquía.Padre = Hijo //OK
    Persona pe = new Programador();
    

    Esto es posible porque un objeto hijo (más especializado) puede hacer todo lo que haga el
    padre (menos especializado) pero no al revés.

    Hijo = Padre //ERROR

    Programador pro = new Persona(); //ERROR
    
 
6 comentarios

Publicado por en 27 septiembre, 2011 en Estudio, Tema 3

 

Etiquetas: , , , , ,

Asignaciones – Heap y Stack.

El Heap (Montículo) y el Stack (Pila) son diferentes memorias que utiliza la Java Virtual Machine de Java.

Mientras que para cada thread en la JVM se tiene un Stack privado, el Heap es un espacio de memoria dinámica único que se crea al inicio de la máquina virtual. El administrador del Heap es el sistema de administración de almacenamiento automático o más conocido como Garbage Collector.

¿Qué se guarda en el Stack?
– variables locales
– variables de referencia
– parámetros y valores de retorno
– resultados parciales
– el control de la invocación y retorno de métodos

¿Qué se guarda en el Heap?
– objetos
– variables de instancia

Ejemplo:

public class EjemploStackYHeap{
    int atributoEntero;
    String atributoCadena;

    public void setAtributoEntero (int x) {
        atributoEntero = x;
    }

    public void setAtributoCadena(String s) {
        atributoCadena = s;
    }

    public static void main (String[] args){
        int enteroLocal = 5;
        String cadenaLocal = "atributo";

        EjemploStackAndHeap e = new EjemploStackAndHeap();
        e.setAtributoEntero (enteroLocal);
        e.setAtributoCadena (cadenaLocal);
    }
}

Comienza la ejecución con main.
Se declara e inicializa una variable de tipo primitivo, enteroLocal.
Se almacena esta variable y su valor en el Stack.

Se declara e inicializa una variable de tipo de referencia.
La variable se crea en el Stack. El objeto se crea en el Heap.
La variable apunta al objeto String en el Heap.

Se llama al constructor EjemploStackAndHeap(). El constructor crea en el Heap el espacio para el objeto y sus atributos. Se inicializan los valores según el tipo de los atributos. En el Stack se crea la variable de referencia e que apunta al objeto en Heap.

Se llama a setAtributoEntero con el parámetro enteroLocal. La variable del método setAtributoEntero x recibe el valor de enteroLocal. Se le asigna el valor de x a atributoEntero. (El método tiene una variable this que apunta al objeto, de esta forma puede acceder a sus atributos).

Se llama a setAtributoCadena con el parámetro cadenaLocal. La variable del método setAtributoCadena s recibe el valor de cadenaLocal. Se le asigna el valor de s a atributoCadena. (El método tiene una variable this que apunta al objeto, de esta forma puede acceder a sus atributos).

Mas información:
http://tech-read.com/2008/12/15/jvm-stack-and-heap/

 
2 comentarios

Publicado por en 19 septiembre, 2011 en Estudio, Tema 3

 

Etiquetas: , , , , ,

 
A %d blogueros les gusta esto: