As vezes, ao utilizar tipos primitivos, podemos sentir falta de algumas funcionalidades dos objetos. A principal dessas funcionalidades está ligada ao uso de genéricos (generics). Os tipos genéricos facilitam muito a reutilização de código sem o enfraquecimento do compilador. Com eles um método não precisa mais retornar
Object
, mas pode retornar um tipo de classe relativo a um dado parâmetro. Os genéricos, porém, só aceitam tipos que descendam da classe Object
. (Isso acontece pela forma como eles são transformados pela compilação.) Por esse motivo, tipos primitivos não podem ser utilizados em genéricos.Outro argumento — esse não é tão inabalável quanto o de genéricos — é que primitivos não podem receber a atribuição de
null
. Para alguns programadores isso pode causar uma quebra de padrão, e até quebrar fluxos de captura de testes.Empacotamento e Desempacotamento (Boxing e Unboxing)
A transição entre dado empacotado ou primitivo pode ser realizada de forma automática pela JVM. Isso, porém, deve ser utilizado com cautela. Como dados complexos, como objetos, são armazenados no espaço de memória Heap e dados simples, como primitivos, ficam na região Stack o processo de boxing/unboxing força a cópia dos dados para da Stack para a Heap, e vice-versa. Se uma aplicação fizer esse processo sem levar isso em consideração, ela pode cair em problemas de performance do processador. Além de lentidão no processador, pode acontecer da memória ficar poluída — já que o coletor de lixo não entra em ação assim que uma variável vira lixo, por outras questões de performance.
Para facilitar esse processo existe o mecanismo de empacotamento e desempacotamento automáticos. O trecho de código:
Integer i = 5;
; funciona perfeitamente.A JVM ainda possuí um mecanismo de otimização para dados empacotados. Ao um novo dado é empacotado a JVM verifica se existe algum objeto que seja a mesma representação do novo. Se ela encontrar, é retornada essa mesma instância. Assim, duas variáveis distintas passam a referenciar um mesmo objeto em Heap. Por essa otimização, utilizar
new Integer(5)
não é recomendado. Esse método ignora a otimização e força a criação de um novo objeto em memória, possivelmente consumindo espaço desnecessário.- Adicionam operações a valores primitivos
- É possível converter um valor primitivo para o seu wrapper ou vice-versa apenas atribuindo um ao outro. Esse processo é chamado de auto-boxing ou auto-unboxing
- Possuem constantes como
MIN_VALUE
eMAX_VALUE
- Permitem facilmente extrair dados de Strings
- São imutáveis
BigDecimal
- Possuí precisão em números decimais
- Possuí métodos para executar diversas operações matemáticas (e.g.
add
,divide
,remainder
,scale
,round
, ...)
- Perfeito para representar números decimais que demandam precisão de casas decimais (como quantias monetárias)