Atribuição a Variáveis Primitivas


Variáveis são recipientes de bits com um designado tipo que representam um valor.
Para variáveis primitivas, os bits representam valores numéricos utilizando um padrão (00000110).
O sinal = é usado para atribuir um valor a uma variável. Atribui-se um valor a uma variável primitiva utilizando uma literal ou o resultado de uma expressão.
Uma literal inteira é sempre int, por isso, para atribuir qualquer literal inteira a um tipo que não seja int (short, byte) o compilador faz o cast automaticamente. Por esse motivo, também todas as operações realizadas com literais numéricas resultam em int, ou seja, se uma operação entre literais numéricos for atribuída a um tipo diferente de int, será necessário fazer cast explicitamente.

public class Atribuicao_Primitivos {    
      //atribuição de uma literal
      int a = 7;
      //atribuição de literal c/ expressão
      int b = a + 2;
      int c = a * b;
     
      //compilador faz cast de int p/ byte
      byte d = 27;
      //pode usar cast explícito
      byte e = (byte) 27;
      /*erro, o resultado de qualquer expressão
       * com literais inteiras sempre resulta
       * em um int, por isso é necessário cast */
      byte f = d + e;
      byte g = (byte) (d + e);
}

Casting Primitivo

Casting permite converter valores primitivos de um tipo para outro tipo. Casts podem ser implícitos ou explícitos. Um cast implícito significa que não é necessário escrever o código para o cast; normalmente ocorre quando a conversão é para ampliação, ou seja, quando se quer colocar uma coisa pequena (byte) em um container maior (int).
Quando ocorre o contrário, ou seja, quando se quer colocar algo grande em um container menor, ocorre o cast explícito. Isso quer dizer que uma variável double, por exemplo, não pode ser atribuída a uma variável int sem que haja um cast explícito.
Quando uma variável maior é atribuída a uma variável menor, os bits que sobram na conversão, ou seja, que não cabem no container, simplesmente são descartados, alterando o resultado final.


public class Cast_Primitivos {    
      /* cast implícito - quando um tipo
       * menor é atribuído a um maior */
      int a = 100;
      long b = a;      
      /* cast explicito - quando um tipo maior é
       * atribuído a um menor; pode haver perda
       * de dados na conversão */
      float c = 100.001f;
      int d = (int)c;
}


Obs.: valores inteiros podem ser atribuídos a um double sem cast explícito, pois qualquer valor inteiro cabe em um container de 64 bits (double). O contrário só ocorre com cast explícito com perda de bits, alterando o resultado final.

Atribuindo Números de Ponto Flutuante

Toda literal de ponto flutuante é implicitamente um double (64 bits), não um float. Por isso, para uma variável float receber qualquer valor de ponto flutuante, é necessário cast explícito de double para float.


public class AtribuicaoPontoFlutuante { 
      /* erro - toda literal de ponto flutuante
       * é implicitamente double, por isso é
       * necessário cast explícito, já que
       * double é maior que float */
      float f = 32.3;
      float g = (float) 32.3;
      float h = 32.3f;
      float i = 32.3F;
}


Atribuindo uma Literal que é maior que a variável

Quando uma variável maior é atribuída a uma menor, gera um erro de compilação caso não seja feito um cast explícito.  Porém, conseqüentemente, o resultado será diferente após o cast, pois Java simplesmente desconsidera os bits de ordem superior que não couberem no container; em outras palavras, haverá perda dos bits da esquerda para a direita.
Existem ainda os operadores de atribuição compostos, que são +=, -=, *= e /=. Todos esses operadores são utilizados com cast implícito.


public class Literais_Grandes {   
      public static void main(String[] args) {
            //erro - um byte só pode guardar 127
            byte a = 128;
            /*é necessário cast eplícito, porém
             * haverá perda de bits, alterando
             * o resultado */      
            byte b = (byte) 128;
            System.out.println(b); //imp. -128     
            /*o resultado de uma expressão de
             * inteiros sempre resulta em um int,
             * por isso é necessário cast explícito*/
            byte var2 = 3;
            var2 = var2 + 7;
            var2 = (byte) (var2 + 7);
            /* porém, quando se utiliza operadores
             * compostos é possível usar o cast
             * implícito */
            byte var = 3;
            var += 7;
      }
}


No exemplo acima, a literal 128 é representada pela seqüência 10000000, porém, como literal é por default um inteiro, então é representado pela seqüência 00000000000000000000000010000000. Quando ocorre o cast, o compilador descarta 24 bits da esquerda para a direita, resultando na seqüência 10000000, que equivale ao byte -128 (o primeiro bit identifica o número como negativo ou positivo).

Atribuindo uma Variável Primitiva a outra Variável Primitiva

Quando uma variável primitiva é atribuída à outra, o valor de uma é copiado pra outra, sem que uma não possua nenhuma relação com a outra. Isso quer dizer que, se depois da atribuição o valor de qualquer uma das duas mudar, o da outra não será afetado, pois somente o conteúdo da variável (os bits que representam o valor) é copiado, e não a sua referência na memória.


public class Copia_Primitivos {   
      public static void main(String[] args) {
            int a = 10;
            System.out.println("A = " + a);
            int b = a;
            System.out.println("B = " + a);
            b = 30;
            System.out.println("Depois: A = " + a +
                                      " B = " + b);
      }
}



Fonte: SCJP Sun Certified Programmer for Java 6 Study Guide

0 comentários:

Postar um comentário