As coleções Java armazenam apenas objetos, não tipos primitivos; no entanto, podemos armazenar as classes de wrapper.
Por que essa restrição?
java
collections
types
primitive-types
JavaUser
fonte
fonte
class
, e sim pela JVM. A instruçãoint i = 1
define um ponteiro para a instância singleton do objeto que defineint
na JVM, configurada com o valor1
definido em algum lugar na JVM. Sim, ponteiros em Java - isso é apenas abstraído de você pela implementação da linguagem. As primitivas não podem ser usadas como genéricos porque o idioma predicado de todos os tipos genéricos deve ser do supertipoObject
- portanto, por queA<?>
compilaA<Object>
em tempo de execução.Respostas:
Foi uma decisão de design Java e que alguns consideram um erro. Contêineres querem Objetos e primitivas não derivam de Objeto.
Este é um lugar que os designers do .NET aprenderam com a JVM e implementaram tipos de valor e genéricos, de modo que o boxe é eliminado em muitos casos. No CLR, contêineres genéricos podem armazenar tipos de valor como parte da estrutura subjacente do contêiner.
Java optou por adicionar suporte genérico 100% no compilador sem suporte da JVM. Sendo a JVM o que é, não suporta um objeto "não-objeto". Os genéricos Java permitem fingir que não há invólucro, mas você ainda paga o preço de desempenho do boxe. Isso é importante para certas classes de programas.
O boxe é um compromisso técnico, e acho que são detalhes de implementação vazando para o idioma. A autoboxing é um bom açúcar sintático, mas ainda é uma penalidade de desempenho. Se alguma coisa, eu gostaria que o compilador me avisasse quando ele caixa automática. (Pelo que sei, agora, escrevi esta resposta em 2010).
Uma boa explicação sobre SO sobre boxe: por que alguns idiomas precisam de boxe e unboxing?
E críticas aos genéricos Java: Por que alguns afirmam que a implementação de genéricos em Java é ruim?
Na defesa de Java, é fácil olhar para trás e criticar. A JVM resistiu ao teste do tempo e é um bom design em muitos aspectos.
fonte
Object.ReferenceEquals
referências do tipoObject
que identificam números inteiros em caixa, mas não deve ser legal passar um valor inteiro]. O auto-unboxing de Java é IMHO apenas desagradável.Facilita a implementação. Como as primitivas Java não são consideradas objetos, você precisará criar uma classe de coleção separada para cada uma dessas primitivas (sem código de modelo para compartilhar).
Você pode fazer isso, é claro, apenas veja GNU Trove , Apache Commons Primitives ou HPPC .
A menos que você tenha coleções realmente grandes, a sobrecarga para os wrappers não importa o suficiente para que as pessoas se importem (e quando você tem coleções primitivas realmente grandes, pode querer se esforçar para usar / construir uma estrutura de dados especializada para elas )
fonte
É uma combinação de dois fatos:
int
não é umObject
)List<?>
é realmente umList<Object>
em tempo de execução)Como ambas são verdadeiras, as coleções Java genéricas não podem armazenar tipos primitivos diretamente. Por conveniência, a caixa automática é introduzida para permitir que tipos primitivos sejam automaticamente encaixotados como tipos de referência. No entanto, não se engane, as coleções ainda estão armazenando referências a objetos.
Isso poderia ter sido evitado? Possivelmente.
int
é anObject
, então não há necessidade de tipos de caixas.fonte
Existe o conceito de boxe automático e unboxing automático. Se você tentar armazenar um
int
em umList<Integer>
compilador Java, ele será automaticamente convertido em umInteger
.fonte
Não é realmente uma restrição, é?
Considere se você deseja criar uma coleção que armazene valores primitivos. Como você escreveria uma coleção que pode armazenar int, float ou char? Provavelmente, você terminará com várias coleções, portanto precisará de uma lista intlist e de uma charlist etc.
Aproveitando a natureza orientada a objetos do Java, quando você escreve uma classe de coleção, ele pode armazenar qualquer objeto, portanto, você precisa de apenas uma classe de coleção. Essa idéia, polimorfismo, é muito poderosa e simplifica muito o design das bibliotecas.
fonte
Acho que podemos ver progresso nesse espaço no JDK, possivelmente no Java 10, com base nesse JEP - http://openjdk.java.net/jeps/218 .
Se você deseja evitar primitivas de boxe em coleções hoje, existem várias alternativas de terceiros. Além das opções de terceiros mencionadas anteriormente, também há Eclipse Collections , FastUtil e Koloboke .
Uma comparação dos mapas primitivos também foi publicada há pouco tempo com o título: Visão geral do HashMap grande: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove . A biblioteca GS Collections (Goldman Sachs) foi migrada para a Eclipse Foundation e agora é Eclipse Collections.
fonte
A principal razão é a estratégia de design java. ++ 1) coleções requer objetos para manipulação e primitivas não são derivadas do objeto, portanto, esse pode ser o outro motivo. 2) Os tipos de dados primitivos Java não são de referência para ex. int não é um objeto.
Superar:-
nós temos o conceito de boxe automático e unboxing automático. portanto, se você estiver tentando armazenar tipos de dados primitivos, o compilador converterá isso automaticamente em objeto dessa classe de dados primitivos.
fonte