Respostas:
Outros mencionaram que certas construções, como Collections
requerem objetos e que os objetos têm mais sobrecarga do que suas contrapartes primitivas (memória e boxing).
Outra consideração é:
Pode ser útil inicializar objetos null
ou enviar null
parâmetros para um método / construtor para indicar o estado ou função. Isso não pode ser feito com primitivos.
Muitos programadores inicializam os números como 0 (padrão) ou -1 para significar isso, mas dependendo do cenário, isso pode ser incorreto ou enganoso.
Isso também definirá o cenário para NullPointerException
quando algo estiver sendo usado incorretamente, o que é muito mais amigável para o programador do que algum bug arbitrário no futuro.
Geralmente, você deve usar tipos primitivos, a menos que precise de um objeto por algum motivo (por exemplo, para colocar em uma coleção). Mesmo assim, considere uma abordagem diferente que não exija um objeto se você quiser maximizar o desempenho numérico. Isso é recomendado pela documentação e este artigo demonstra como a caixa automática pode causar uma grande diferença de desempenho.
Integer
é mais legível do que int
.
Em minha opinião, se meus membros de classe são variáveis de invólucro, isso não depende de valores padrão, o que é um comportamento amigável do desenvolvedor.
1
class Person {
int SSN ; // gets initialized to zero by default
}
2
class PersonBetter {
Integer SSN; //gets initialized to null by default
}
No primeiro caso, você não pode manter o valor SSN não inicializado. Pode doer se você não estiver verificando se o valor foi definido antes de tentar usá-lo.
No segundo caso, você pode manter o SSN inicializado com nulo. O que pode levar a NullPointerException, mas é melhor do que inserir inadvertidamente valores padrão (zero) como SSN no banco de dados sempre que você tentar usá-lo sem inicializar o campo SSN.
PersonBuilder
cria um que lança uma exceção se o SSN não for definido antes de chamar "build" para obter a Person
instância. Acho que esse tipo de coisa é excessivo, mas é o que a linguagem Java promove para padrões adequados.
Eu só usaria os tipos de invólucro se necessário.
Em usá-los você não ganha muito, além do fato de que eles são Objects
.
E você perde sobrecarga no uso de memória e tempo gasto boxing / unboxing.
Praticamente encontrei uma situação em que o uso da classe wrapper pode ser explicado.
Eu criei uma classe de serviço que tinha uma long
variável de tipo
long
- quando não inicializada, será definida como 0 - isso será confuso para o usuário quando exibido na GUI Long
- quando não inicializada, ela será configurada para null
- este valor nulo não aparecerá na GUI.Isso se aplica á Boolean
também a onde os valores podem ser mais confusos quando usamos primitivos boolean
(já que o valor padrão é falso).
As coleções são o caso típico de objetos de invólucro Java simples. No entanto, você pode considerar dar ao Wrapper um significado mais específico no código (objeto de valor).
IMHO, quase sempre há um benefício em usar objetos de valor quando se resume à legibilidade e manutenção do código. Encapsular estruturas de dados simples dentro de objetos quando eles têm certas responsabilidades geralmente simplifica o código. Isso é algo muito importante no design orientado a domínio .
É claro que existe o problema de desempenho, mas tendo a ignorar isso até ter a possibilidade de medir o desempenho com dados adequados e fazer ações mais direcionadas para a área problemática. Também pode ser mais fácil entender o problema de desempenho se o código também for fácil de entender.
o desempenho de aplicativos que são dominados por cálculos numéricos pode se beneficiar muito com o uso de primitivas.
tipos primitivos, usa-se o operador ==, mas para wrapper a escolha preferida é chamar o método equals ().
"Tipos primitivos considerados prejudiciais" porque misturam "semântica procedural em um modelo orientado a objetos uniforme.
Muitos programadores inicializam os números como 0 (padrão) ou -1 para significar isso, mas dependendo do cenário, isso pode ser incorreto ou enganoso.
Se você deseja usar coleções, você deve usar classes Wrapper.
Tipos primitivos são usados para matrizes. Além disso, para representar dados que não têm comportamento, por exemplo, um contador ou uma condição booleana.
Desde o autoboxing, a fronteira "quando usar primitivo ou invólucro" tornou-se bastante confusa.
Mas lembre-se, Wrappers são objetos, então você obtém todos os recursos sofisticados do Java. Por exemplo, você pode usar a reflexão para criar objetos inteiros, mas não valores inteiros. As classes de wrapper também possuem métodos como valueOf.
Se você deseja criar um tipo de valor. Algo como ProductSKU ou AirportCode.
Quando um tipo primitivo (string em meus exemplos) define igualdade, você deseja substituir a igualdade.
Valores primitivos em Java não são objetos. Para manipular esses valores como objeto, o pacote java.lang fornece uma classe de invólucro para cada tipo de dados primitivo.
Todas as classes de Wrapper são finais. Os objetos de todas as classes de wrapper que podem ser iniciadas são imutáveis, o que significa que o valor no objeto de wrapper não pode ser alterado.
Embora a classe void seja considerada uma classe wrapper, ela não envolve nenhum valor primitivo e não pode ser iniciada. Ele não tem um construtor público, apenas denota um objeto de classe que representa a palavra-chave void.