Texto de: Geraldo Daros
Introdução
Na programação, a criação e manipulação de variáveis são atividades cotidianas e no Java, essa tarefa assume uma relevância especial. A maneira como manipulamos variáveis nessa linguagem pode ser mais consciente e intrigante do que parece à primeira vista, já que a simples mudança de Double
para double
vai além de uma questão de capitalização; internamente, diversas operações são impactadas por essa escolha.
Neste artigo, exploraremos os conceitos de tipos primitivos e wrappers em Java, revelando as complexidades por trás dessas escolhas. Você aprenderá não apenas a distinção entre eles, mas também entenderá em que situações é mais adequado optar por um ou outro.
Tipos Primitivos
O que são afinal os tipos primitivos? São os tipos mais básicos de variáveis que o Java possui, sendo eles:
- byte : Aceita tipos numéricos inteiros com um valor mínimo de -128 e um valor máximo de 127;
- char : Aceita apenas um caractere entre aspas simples, dessa forma
char a = 'A'
; - short : Aceita tipos numéricos inteiros com valor mínimo de -32.768 e valor máximo de 32.767;
- int : Aceita tipos numéricos inteiros com valor mínimo de -2³¹ e um valor máximo de 2³¹-1;
- long : Aceita tipos numéricos inteiros com valor mínimo de -2⁶³ e um valor máximo de 2⁶³-1;
- float : Aceita dados numéricos com pontos flutuantes e não tem valor mínimo e máximo na documentação – caso queira ver melhor acesse a documentação deixada abaixo;
- double : Aceita dados numéricos com pontos flutuantes e não tem valor mínimo e máximo na documentação;
- boolean : Aceita apenas os valores
true
oufalse
;
Documentação oficial dos tipos primitivos.
Agora, com o conhecimento dos tipos primitivos, notamos que eles servem apenas para armazenar valores e nada mais. No entanto, em alguns momentos, podemos precisar de algo além de simplesmente armazenar um valor. Precisamos também de algumas funcionalidades que são extremamente recorrentes, como mudar de um tipo para o outro, comparar valores e várias outras operações. Por isso, no Java, também temos as classes Wrappers para nos auxiliar nesse aspecto, não apenas armazenando um valor, mas também disponibilizando outras funcionalidades relacionadas a esse valor!
Classes Wrappers
As classes Wrappers são como tipos primitivos, porém 'aprimoradas'. Na verdade, são literalmente classes (objetos instanciáveis) que contêm um tipo primitivo para armazenar o valor e também oferecer muitas outras funcionalidades por meio de seus métodos.
No Java temos 8 tipos primitivos e temos um Wrapper para cada tipo primitivo. São eles:
- byte : Representado por Byte
- char : Representado por Character
- short : Representado por Short
- int : Representado por Integer
- long : Representado por Long
- float : Representado por Float
- double : Representado por Double
- boolean:– Representado por Boolean
Na hora de criar uma variável nada muda; o Java realiza todo esse trabalho nos bastidores. Além disso, a maioria dos Wrappers apenas começa com uma letra maiúscula. Essa é a diferença entre o nome do tipo primitivo e as classes Wrappers. Pequena, não é mesmo? No entanto, a diferença entre eles é realmente maior do que apenas isso.
Não entraremos nos mínimos detalhes sobre cada uma as diversas funcionalidades que os Wrappers nos proporcionam, mas temos métodos para compará-los, fazer conversão de tipo de valor e muito mais. Por exemplo, métodos do Double:
- toString(): Transforma o valor em uma String.
- compare(): Compara dois valores double; é um método estático e pode ser chamado da classe Double.
Diferença entre Wrapper e Tipos Primitivos
Afinal, qual a diferença de uma Wrapper para um tipo primitivo? Primeiramente, o tipo primitivo serve unicamente para guardar um valor, apenas isso. Já os Wrappers, além de guardarem os valores, fornecem diversas funcionalidades essenciais para diversas tarefas do dia a dia do desenvolvedor.
Mas se os Wrappers são mais completos, possuem mais vantagens e funcionalidades, por que ainda usamos os tipos primitivos? A resposta é simples: como os Wrappers são objetos, eles consomem mais memória do que os tipos primitivos, afetando o desempenho da sua aplicação.
Agora veremos um exemplo de diferença de consumo de memória sobre os tipos primitivos e classes Wrappers.
Por exemplo, a diferença no uso de memória de cada variável criada com tipo primitivo ou com Wrappers, é bem significativa, não? É evidente a diferença, mas não se preocupe, não pare de usar os Wrappers! Eles foram feitos para isso, basta usar as variáveis certas para os momentos certos e tudo ficará bem.
Então, tente verificar realmente a necessidade de um Wrapper, se for necessário o uso de alguma funcionalidade que vem do Wrapper, use-o! Caso não seja necessário, pense em adaptar para um tipo primitivo.
Conclusão
Com este artigo, vocês terão uma compreensão mais clara das diferenças entre tipos primitivos e classes Wrappers. Embora não seja uma comparação extremamente simplificada, serve como um excelente ponto de partida para estar atento a algumas más práticas, bem como ao uso e desperdício de memória.
Espero que tenham assimilado essa distinção e que isso tenha enriquecido o seu conhecimento sobre o assunto.