Casting e Promoção
Autor: Marcos Costa  | Publicado: 2012-09-24T20:53:00-07:00



Alguns valores são incompatíveis se você tentar fazer uma atribuição direta. Quando uma variável tem o tipo double será impossível representar em uma variável do tipo int. Porque não se sabe se realmente é um número inteiro ou não. Resumindo: Casting é quando precisamos ordenar que o número quebrado seja moldado como um número inteiro (nesse caso).

Ex:
double d3 = 3.14;
int i = (int) d3;

Repare que nesse caso irá imprimir o número "3". Pois o int só recebe valores inteiros e o ".14" será ignorado, uma vez que nesse exemplo se trata de um número inteiro.

O Casting foi feito para moldar a variável.

Exemplo:

long x = 1000;
int i = x; //há perda de informação

Se quisermos fazer realmente isso:

long x = 1000;
int i = (int) x;

Lembre-se que o único tipo primitivo que não pode ser atribuído a nenhum outro tipo é o Boolean.


Mais sobre Casting


Utilizamos o casting ou moldagem para converter&nbsp;um objeto ou primitiva de um tipo para outro. Podemos converter&nbsp;um double em um int, ou uma subclasse em uma superclasse.

A regra fundamental para moldagem é: o casting&nbsp;não modifica o objeto ou valor que está sendo moldado; porém,&nbsp;o receptor do cast constitui um novo objeto ou um novo tipo.



O casting de dados primitivos ocorre com bastante&nbsp;frequência. A maneira pelo qual o casting age depende da precisão&nbsp;dos dados envolvidos. Por sua vez, a precisão depende da quantidade&nbsp;de informações que um tipo pode conter; assim, um tipo de&nbsp;ponto flutuante double tem maior precisão que um float, pois&nbsp;o primeiro é um tipo de 64 bits e o segundo, de 32 bits.

Sempre que houver uma transferência de dados&nbsp;de um tipo menos preciso para um mais preciso, o casting explícito&nbsp;não é obrigatório.



int i = 3;double pi = i + .14159;



Já a transferência de dados de um tipo mais&nbsp;preciso para um menos preciso requer um casting explícito.&nbsp;Isso ocorre porque pode haver perda de dados durante a moldagem.&nbsp;Java pretende alertar o programador do possível perigo de&nbsp;uma conversão desse tipo:

double pi = 3.14159;
int i = (int)pi; // variável definida como 3; perda de .14159



O casting entre objetos requer um pouco mais&nbsp;de cuidado. Para ilustrar uma aplicação de casting para objetos,&nbsp;vamos analisar a classe Hashtable do JDK da Sun. Ela utiliza&nbsp;instâncias da classe Object e as insere em uma tabela de hash,&nbsp;por meio de um método chamado put(), no qual um String é usado&nbsp;como chave.

Vamos supor que você tenha uma classe chamada&nbsp;MinhaClasse e um String usado como chave em uma variável chave.&nbsp;Incluímos essa chave em um objeto Hashtable da&nbsp;seguinte maneira:

MinhaClasse MeuObjeto;
hash.put(chave.MeuObjeto);

Vamos supor que seja necessária a armazenagem&nbsp;de MeuObjeto como Object próprio, ou seja, um cast de uma&nbsp;subclasse como uma superclasse. Isso seria feito da seguinte&nbsp;forma:

hsh.put(chave,(Object)MeuObjeto);

Ao fazer este cast, perde-se a funcionalidade&nbsp;de MeuObjeto.

É possível também converter o Object retronado&nbsp;por get() no MeuObjeto original, através de:

MinhaClasse MeuObjeto;hash.put(chave,MeuObjeto);MinhaClasse MeuObjeto2 = (MinhaCLasse)hash.get(chave);// obtém de volta o MeuObjeto original

Não é possível fazer o cast de tipos de dados&nbsp;primitivos como objetos ou vice-versa. Entretanto, pode-se&nbsp;realizar essas conversões utilizando as classes wrappers de&nbsp;tipos discutidas no início deste capítulo.

Regras de Escopo



Quando uma variável é referenciada no interior&nbsp;de um método, Java procura primeiro uma declaração em um bloco&nbsp;mais externo. Se não encontra enhuma declaração, Java percorre

os blocos alinhados, até alcançar a definição do método. Se&nbsp;a variável se encontrar em qualquer lugar no interior de um&nbsp;método, ela tem prioridade sobre uma variável de instância&nbsp;ou de classe com nome semelhante. Por isso, encontramos frequentemente&nbsp;códigos como este:

public RegistroSimples(String
nome, String email) {
this.nome = nome;
this.email = email;
}

A palavra&nbsp;this&nbsp;é usada nesse caso para diferenciar a variável de instância&nbsp;da variável local.

Tratamento de Exceções



Um grande desafio atualmente em programação&nbsp;é saber como lidar com erros durante a execução de maneira&nbsp;eficiente. Tradicionalmente, os programadores gerenciam os&nbsp;problemas pela passagem de códigos de sucesso ou falha em&nbsp;instruções return. Então, as instruções de chamada verificam

o código de retorno em uma instrução if … else. Se a função&nbsp;é bem-sucedida, é chamada uma sequência de ações: caso contrário,&nbsp;é executada outra série de funções.

Existem alguns problemas nesse tipo de abordagem.&nbsp;O excesso de instruções if … else resulta em um aumento&nbsp;considerável do tamanho do código. Além disso, essa solução&nbsp;não implementa uma forte verificação de erros.



Java possui um considerável esquema de verificação&nbsp;de erros. Muitos deles são interceptados pelo próprio compilador,&nbsp;ao invés de serem detectados somente na execução. Porém, se&nbsp;alguma falha "passar" pelo compilador, o exame em&nbsp;uma pilha (veremos mais tarde que a virtual machine de Java

é toda baseada na pilha) irá facilitar a busca do problema.

Os tratadores de exceção e&nbsp;as classes de exceções



As exceções podem ser de diferentes tipos ou,&nbsp;mais especificamente, de classes distintas. Por exemplo, NumberFormatException&nbsp;se refere a uma classe específica. Quando uma exceção é gerada,&nbsp;o sistema runtime do Java procura um tratador apropriado para&nbsp;interceptar a falha. O fato de um tratador ser ou não apropriado&nbsp;para uma determinada exceção está relacionado com a classe


da exceção.






Vejamos um exemplo: a classe ArithmeticException&nbsp;representa erros causados por operações aritméticas inválidas&nbsp;(geralmente uma divisão por zero). Os objetos da classe ArrayIndexOutOfBoundsException&nbsp;são emitidos quando é acessado um índice de array inválido.


A classe Exception éutilizada para representar a classe geral&nbsp;de exceções; na verdade, as outras classes de exceções que&nbsp;foram discutidas são subclasses de Exception. Vejamos como&nbsp;essas exceções são usadas:




try {
int x = Integer.parse(s);
int y = Integer.parse(s2);
int index = Integer.parseInt(s3);
int a[] = new Int[5];




a[index] = x/y;System.out.println("Tudo está funcionando");}catch (ArithmeticException e) {System.out.println("Exceção aritmética");}catch (ArrayIndexOutOfBoundsException e) {System.out.println("Exceção de índice de array fora doslimites");}catch (NumberFormatException e) {System.out.println("Impossível converter String em número");}catch (Eception e) {System.out.println("Exceção genérica");}

A primeira parte do código utiliza três Strings&nbsp;de entrada e tenta convertê-los em inteiros; se a conversão&nbsp;falha, é emitido um objeto NumberFormatException. No entanto,&nbsp;a terceira cláusula catch irá interceptar o objeto emitido.&nbsp;Se a cláusla não existisse, a última cláusula catch iria detectar&nbsp;o problema, porque NumberFormatException é uma subclasse de&nbsp;Exception.

Depois que os Strinfs são convertidos em números,&nbsp;o programa tenta dividir os números. Se houver uma tentativa&nbsp;de divisão por zero, é emitido um objeto ArithmeticException.&nbsp;O objeto é então interceptado pela cláusula catch de ArthmeticException.&nbsp;Também poderemos ter exceções aninhadas. Vejamos&nbsp;uma variação do código anterior:

int y = 0;int z = 0;int x = 0;int index = 0;int a[] = new int[5];

try {

x = Integer.parseInt(s);y = Integer.parseInt(s2);

index = Integer.parseInt(s3);a[index] = x/y;System.out.println(‘Tudo está funcionando");}catch (ArithmeticException e) {System.out.println("Exceção aritmética. Experimente atribuirzero");

try {a[index] = x/z;}catch (ArithmeticException e2) {System.out.println("Outra exceção aritmética");}catch (ArrayIndexOutOfBoundsException e)System.out.println("Exceção de índice de arrays forados limites");}catch (NumberFormatException e) {System.out.println("Não é possível converter String emnúmero");}catch (Exception e) {System.out.println("Exceção genérica");}

Se a variável y do tipo int tiver valor 0,&nbsp;é emitida uma ArithmeticException. Quando esta exceção é interceptada,&nbsp;o código tenta executar outra divisão, que também é inválida.&nbsp;Este novo erro é interceptado por um bloco catch de ArithmeticException.&nbsp;Se o erro fosse, ao invés de uma divisão por zero (emissão&nbsp;da exceção ArithmeticException), um índice inválido, seria&nbsp;emita a exceção ArrayIndexOutOfBoundsException.

A Tabela abaixo indica todos os casting possíveis em Java.



A indicação Impl quer dizer que aquele cast é implícito e automático





Fonte:&nbsp;http://imasters.com.br/artigo/464/java/regras-de-casting

Publicado por: Marcos Costa


Gostou da publicação?

Tem alguma crítica, sugestão ou idéia?

Mande-nos um email