Neste artigo, veremos um recurso em Java chamado autoboxing/unboxing . Autoboxing e unboxing são funções de conversão de tipos primitivos em tipos de objetos e vice-versa. Autoboxing e unboxing em Java - 1Todo o processo é executado automaticamente pelo Java Runtime Environment (JRE). Mas você deve ter cuidado ao implementar esta função, porque... Isso pode afetar o desempenho do seu programa.

Introdução

Nas versões anteriores ao JDK 1.5, não era fácil converter tipos de dados primitivos como int, char, float, doubleem suas classes wrapper Integer, Character, Float, Double. A partir do JDK 5, esta funcionalidade, convertendo tipos primitivos em objetos equivalentes, é implementada automaticamente. Esta propriedade é conhecida como Autoboxing . O processo inverso, respectivamente, é Unboxing , ou seja. o processo de conversão de objetos em seus tipos primitivos correspondentes. O código de exemplo para autoboxing e unboxing é fornecido abaixo: Autoboxing
Integer integer = 9;
Desembalagem
int in = 0;
in = new Integer(9);
Quando é usada a embalagem e desembalagem automática? Autoboxing é usado pelo compilador Java nas seguintes condições:
  • Quando um valor de um tipo primitivo é passado para um método como parâmetro de método, que espera um objeto da classe wrapper correspondente.
  • Quando um valor de um tipo primitivo é atribuído a uma variável da classe wrapper correspondente.
Considere o seguinte exemplo: Listagem 1: Código simples mostrando autoboxing
public int sumEvenNumbers(List<Integer> intList ) {
int sum = 0;
for (Integer i: intList )
if ( i % 2 == 0 )
sum += i;
return sum;
}
Antes do jdk 1.5, o código acima teria causado um erro de compilação porque o operador restante % e o unário mais += não podiam ser aplicados a uma classe wrapper. Mas no jdk 1.5 e superior esse código compila sem erros, convertendo Integer em int. O unboxing é usado pelo compilador Java nas seguintes condições:
  • Quando um objeto é passado como parâmetro para um método que espera um tipo primitivo correspondente.
  • Quando um objeto é atribuído a uma variável do tipo primitivo correspondente.
Considere o seguinte exemplo: Listagem 2: Código simples mostrando unboxing
import java.util.ArrayList;
import java.util.List;

public class UnboxingCheck {

public static void main(String[] args) {
Integer in = new Integer(-8);

// 1. Распаковка через вызов метода
int absVal = absoluteValue(in);
System.out.println("absolute value of " + in + " = " + absVal);

List<Double> doubleList = new ArrayList<Double>();

// Автоупаковка через вызов метода
doubleList.add(3.1416);

// 2. Распаковка через присвоение
double phi = doubleList.get(0);
System.out.println("phi = " + phi);
}

public static int absoluteValue(int i) {
return (i < 0) ? -i : i;
}
}
Autoboxing e unboxing permitem que o desenvolvedor escreva código fácil de ler e entender. A tabela a seguir mostra os tipos de dados primitivos e seus objetos wrapper correspondentes.
Tipos primitivos Aulas de concha
boleano boleano
byte Byte
Caracteres Personagem
flutuador Flutuador
interno Inteiro
longo Longo
curto Curto
Tabela 1: Tipos primitivos e classes wrapper equivalentes com operadores de comparação Autoboxing e unboxing podem ser usados ​​com operadores de comparação. O trecho de código a seguir ilustra como isso acontece: Listagem 3: Código de exemplo mostrando autoboxing e unboxing com um operador de comparação
public class BoxedComparator {
  public static void main(String[] args) {
      Integer in = new Integer(25);
      if (in < 35)
          System.out.println("Value of int = " + in);
  }
}
Autoempacotamento e descompactação ao sobrecarregar um método A compactação e descompactação automática são executadas ao sobrecarregar um método com base nas seguintes regras:
  • A expansão “derrota” a embalagem numa situação em que há uma escolha entre expansão e embalagem; a expansão é preferível.
Listagem 4: Exemplo de código mostrando o benefício da sobrecarga
public class WideBoxed {
  public class WideBoxed {
  static void methodWide(int i) {
       System.out.println("int");
   }

  static void methodWide( Integer i ) {
      System.out.println("Integer");
  }

  public static void main(String[] args) {
      short shVal = 25;
      methodWide(shVal);
  }
 }
}
Saída do programa - tipoint
  • A expansão supera o número variável de argumentos Numa situação em que se torna uma escolha entre expansão e número variável de argumentos, a expansão é preferível.
Listagem 5: Exemplo de código mostrando o benefício da sobrecarga
public class WideVarArgs {

    static void methodWideVar(int i1, int i2) {
      System.out.println("int int");
    }

    static void methodWideVar(Integer... i) {
       System.out.println("Integers");
    }

   public static void main( String[] args) {
       short shVal1 = 25;
      short shVal2 = 35;
     methodWideVar( shVal1, shVal2);
   }
  }
  • O empacotamento supera o número variável de argumentos Em uma situação em que se torna uma escolha entre o empacotamento e o número variável de argumentos, o empacotamento é preferível.
Listagem 6: Exemplo de código mostrando o benefício da sobrecarga
public class BoxVarargs {
     static void methodBoxVar(Integer in) {
         System.out.println("Integer");
     }

     static void methodBoxVar(Integer... i) {
         System.out.println("Integers");
     }
     public static void main(String[] args) {
         int intVal1 = 25;
         methodBoxVar(intVal1);
    }
}
Você deve manter o seguinte em mente ao usar o Auto Packing: Como sabemos, todo bom recurso tem uma desvantagem. A embalagem automotiva não é exceção nesse aspecto. Algumas notas importantes que um desenvolvedor deve ter em mente ao usar este recurso:
  • Comparar objetos com o ==operador '' pode ser confuso, pois pode ser aplicado a tipos e objetos primitivos. Quando este operador é aplicado a objetos, ele na verdade compara referências aos objetos, não aos próprios objetos.
Listagem 7: Exemplo de código mostrando a comparação.
public class Comparator {
   public static void main(String[] args) {
     Integer istInt = new Integer(1);
       Integer secondInt = new Integer(1);

       if (istInt == secondInt) {
         System.out.println("both one are equal");

       } else {
          System.out.println("Both one are not equal");
      }
   }
}
  • Misturando objetos e tipos primitivos com operadores de igualdade e relacionais. Se compararmos um tipo primitivo com um objeto, então o objeto é unboxed, o que pode ser lançado NullPointerExceptionse o object null.
  • Cache de objetos. O método valueOf()cria um contêiner de objetos primitivos que ele armazena em cache. Como os valores são armazenados em cache no intervalo de -128 a 127, inclusive, esses objetos armazenados em cache podem se comportar de maneira diferente.
  • Degradação de desempenho. Autoboxing ou unboxing degrada o desempenho do aplicativo porque cria um objeto indesejado que força o coletor de lixo a ser executado com mais frequência.
Desvantagens do AutoBoxing Embora o AutoBoxing tenha diversas vantagens, ele apresenta as seguintes desvantagens: Listagem 8: Código de amostra mostrando o problema de desempenho.
public int sumEvenNumbers(List intList) {
          int sum = 0;
          for (Integer i : intList) {
              if (i % 2 == 0) {
                  sum += i;
              }
          }
         return sum;
   }
Nesta seção do código, sum +=i ele será expandido para sum = sum + i. Começando com o +operador ' ', a JVM inicia o unboxing porque o +operador ' ' não pode ser aplicado a um objeto Integer. E então o resultado é compactado automaticamente. Antes do JDK 1.5, os tipos de dados inte inteiros eram diferentes. Em caso de sobrecarga do método, esses dois tipos foram utilizados sem problemas. Com o advento da embalagem/desembalagem automática, isto tornou-se mais difícil. Um exemplo disso é o método sobrecarregado remove()em ArrayList. A classe ArrayListpossui dois métodos delete - remove(index)e remove(object). Neste caso, a sobrecarga do método não ocorrerá e o método correspondente será chamado com os parâmetros apropriados.

Conclusão

Autoboxing é um mecanismo para converter implicitamente tipos de dados primitivos em classes wrapper (objetos) correspondentes. O compilador usa o método valueOf()para converter tipos primitivos em objetos, e os métodos IntValue(), doubleValue()etc., para obter os tipos primitivos do objeto. Autoboxing converte o tipo booleano booleanem Boolean, byteem Byte, charem Character, floatem Float, intem Integer, longem Long, shortem Short. A desembalagem ocorre na direção inversa. Artigo original