JavaRush /Blogue Java /Random-PT /Embrulhar, desembrulhar e embalar

Embrulhar, desembrulhar e embalar

Publicado no grupo Random-PT
Olá! Você já está bastante familiarizado com os tipos primitivos e já trabalhou muito com eles. Embrulhar, desembrulhar e embalar - 1Os primitivos na programação, e em Java em particular, têm muitas vantagens: ocupam pouca memória, aumentando assim a eficiência do programa, e são claramente divididos em intervalos de valores. Porém, no processo de aprendizagem de Java, repetimos mais de uma vez, como um mantra, “ em Java tudo é um objeto ”. Mas os primitivos são uma refutação direta dessas palavras. Eles não são objetos. Então o princípio “tudo é um objeto” é falso? Na verdade. Em Java, todo tipo primitivo tem seu irmão gêmeo, a classe wrapper ( Wrapper). O que é um invólucro? Um wrapper é uma classe especial que armazena o valor de um primitivo dentro de si. Mas como se trata de uma classe, ela pode criar suas próprias instâncias. Eles armazenarão os valores primitivos necessários, embora sejam objetos reais. Os nomes das classes wrapper são muito semelhantes aos nomes das primitivas correspondentes ou coincidem completamente com eles. Portanto, será muito fácil lembrá-los.
Classes wrapper para tipos de dados primitivos
Tipos de dados primitivos Classes de wrapper
interno Inteiro
curto Curto
longo Longo
byte Byte
flutuador Flutuador
dobro Dobro
Caracteres Personagem
boleano boleano
Os objetos da classe Wrapper são criados como qualquer outro:
public static void main(String[] args) {

   Integer i = new Integer(682);

   Double d = new Double(2.33);

   Boolean b = new Boolean(false);
}
As classes wrapper permitem atenuar as desvantagens dos tipos primitivos. A mais óbvia é que os primitivos não possuem métodos . Por exemplo, eles não possuem um método toString(), então você não pode, por exemplo, converter um número intem uma string. Mas com uma classe wrapper Integeré fácil.
public static void main(String[] args) {

   Integer i = new Integer(432);

   String s = i.toString();
}
Também haverá dificuldades com a transformação reversa. Digamos que temos uma string que sabemos com certeza que contém um número. Porém, no caso de um tipo primitivo, intnão conseguiremos pegar esse número da string e transformá-lo, de fato, em um número. Mas graças às classes wrapper, agora temos esta oportunidade.
public static void main(String[] args) {

   String s = "1166628";

   Integer i = Integer.parseInt(s);

   System.out.println(i);
}
Saída: 1166628 Recuperamos com sucesso um número de uma string e o atribuímos a uma variável de referência Integer i. A propósito, sobre links. Você já sabe que os parâmetros são passados ​​aos métodos de diferentes maneiras: os primitivos são passados ​​por valor e os objetos são passados ​​por referência. Você pode usar esse conhecimento na hora de criar seus métodos: se o seu método funciona, por exemplo, com números fracionários, mas você precisa da lógica de passagem por referência, você pode passar parâmetros para o método Double/Floatao invés de double/float. Além dos métodos, as classes wrapper possuem campos estáticos que são muito convenientes de usar. Por exemplo, imagine que agora você se depara com uma tarefa: imprimir o número máximo possível no console inte, em seguida, o número mínimo possível. A tarefa parece elementar, mas mesmo assim dificilmente você conseguirá realizá-la sem o Google. E as classes wrapper permitem que você resolva facilmente os seguintes “problemas do dia a dia”:
public class Main {
   public static void main(String[] args) {

       System.out.println(Integer.MAX_VALUE);
       System.out.println(Integer.MIN_VALUE);
   }
}
Esses campos permitem que você não se distraia de tarefas mais sérias. Sem falar que no processo de impressão do número 2147483647 (este é exatamente MAX_VALUE) não é surpreendente digitá-lo incorretamente :) Além disso, em uma das palestras anteriores já chamamos a atenção para o fato de que objetos de classes wrapper são imutáveis .
public static void main(String[] args) {

   Integer a = new Integer(0);
   Integer b = new Integer(0);

   b = a;
   a = 1;
   System.out.println(b);
}
Saída: 0 O objeto para o qual a referência apontou originalmente аnão mudou seu estado, caso contrário, o valor btambém teria mudado. Assim como acontece com String, em vez de alterar o estado do objeto wrapper, um objeto inteiramente novo é criado na memória. Por que os criadores do Java decidiram manter os tipos primitivos na linguagem? Como tudo deveria ser um objeto, e já temos classes wrapper que podem ser usadas para expressar tudo o que os primitivos expressam, por que não deixá-los na linguagem e remover os primitivos? A resposta é simples: desempenho. Os tipos primitivos são chamados de primitivos porque são desprovidos de muitos recursos “pesados” dos objetos. Sim, um objeto possui muitos métodos convenientes, mas nem sempre você precisa deles. Às vezes você só precisa do número 33, ou 2,62, ou do valor de true/ false. Em situações onde todos os benefícios dos objetos não são importantes e não são necessários para o funcionamento do programa, os primitivos farão um trabalho muito melhor.

Empacotamento/desempacotamento automático

Um dos recursos das primitivas e suas classes wrapper em Java é o autoboxing/autounboxing. Embrulhar, desembrulhar e embalar - 2 Vamos entender esse conceito. Como você e eu já aprendemos anteriormente, Java é uma linguagem orientada a objetos. Isso significa que todos os programas escritos em Java são compostos de objetos. Primitivos não são objetos. No entanto, à variável de classe wrapper pode ser atribuído um valor de um tipo primitivo. Este processo é chamado de autoboxing . Da mesma forma, uma variável de tipo primitivo pode receber um objeto de uma classe wrapper. Este processo é chamado de autounboxing . Por exemplo:
public class Main {
   public static void main(String[] args) {
       int x = 7;
       Integer y = 111;
       x = y; // auto unpacking
       y = x * 123; // autopacking
   }
}
Na linha 5, atribuímos ao primitivo x o valor de y, que é um objeto da classe wrapper Integer. Como você pode ver, nenhuma ação adicional é necessária para isso: o compilador sabe disso inte Integer, de fato, é a mesma coisa . Isso é descompactação automática. A mesma coisa acontece com o autoboxing na linha 6: ao objeto y é facilmente atribuído o valor de primitivos (x*123). Este é um exemplo de empacotamento automático. É por isso que a palavra “auto” é adicionada: para atribuir referências primitivas a objetos de suas classes wrapper (e vice-versa) você não precisa fazer nada, tudo acontece automaticamente . Conveniente, certo? :) Outra comodidade muito grande de empacotamento/desempacotamento automático se manifesta na operação dos métodos. O fato é que os parâmetros do método também estão sujeitos a autopacking e autounpacking . E, por exemplo, se um deles receber dois objetos como entrada Integer, podemos facilmente passar primitivos comuns para lá int!
public class Main {
   public static void main(String[] args) {

       printNumber(7);//regular int, even without a variable
   }

   public static void printNumber(Integer i) {
       System.out.println("You entered a number" + i);
   }
}
Saída: Você inseriu o número 7. Funciona ao contrário:
public class Main {
   public static void main(String[] args) {

       printNumber(new Integer(632));
   }

   public static void printNumber(int i) {
       System.out.println("You entered a number" + i);
   }
}
Um ponto importante a lembrar: autoboxing e unboxing não funcionam para arrays !
public class Main {
   public static void main(String[] args) {

       int[] i = {1,2,3,4,5};

       printArray(i);//error, won't compile!
   }

   public static void printArray(Integer[] arr) {
       System.out.println(Arrays.toString(arr));
   }
}
Tentar passar um array de primitivos para um método que recebe um array de objetos como entrada causará um erro de compilação. Finalmente, vamos mais uma vez comparar brevemente primitivos e wrappers Primitivos:
  • tem uma vantagem de desempenho
Invólucros:
  • Eles permitem que você não viole o princípio “tudo é um objeto”, para que números, símbolos e valores booleanos verdadeiro/falso não caiam fora deste conceito
  • Expanda a capacidade de trabalhar com esses valores fornecendo métodos e campos convenientes
  • Necessário quando algum método pode funcionar exclusivamente com objetos
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION