Autoboxing
Por que você não precisa se preocupar se uma classe primitiva ou empacotadora é retornada, você pergunta? Desde o Java 5, você pode digitar o valor primitivo e o Java irá convertê-lo para o classe wrapper relevante para você. Isso é chamado de autoboxing. Vamos ver um exemplo:
4: List weights = new ArrayList<>();
5: weights.add(50.5); // [50.5]
6: weights.add(new Double(60)); // [50.5, 60.0]
7: weights.remove(50.5); // [60.0]
8: double first = weights.get(0); // 60.0
A linha 5 autoboxes o primitivo double em um objeto Double e adiciona isso à Lista.
A linha 6 mostra que você ainda pode escrever o código com o longo caminho e passar um objeto wrapper. A Linha 7 novamente faz autoboxes no objeto wrapper e passa para remove() . A linha 8 recupera o Double e faz unboxes em um primitivo double.
O que você acha que acontece se você tentar fazer unbox com um nulo ?
3: List heights = new ArrayList<>();
4: heights.add(null);
5: int h = heights.get(0); // NullPointerException
Na linha 4, adicionamos um nulo à lista. Isso é legal porque uma referência nula pode ser atribuída para qualquer variável de referência. Na linha 5, tentamos fazer unbox do null para um primitivo int. Isto é um problema. Java tenta obter o valor int de null. Desde que chamar qualquer método com null dá um NullPointerException, é exatamente isso que recebemos. Tenha cuidado quando você vê nulo em relação com autoboxing.
Tenha cuidado quando houver autoboxing em Integer. O que você acha que esse código gera?
List numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.remove(1);
System.out.println(numbers);
Realmente produz 1. Depois de adicionar os dois valores, a List contém [1, 2]. Nós então pedimos que o elemento com índice 1 seja removido. É isso mesmo: índice 1. Porque já existe um remove() método que usa um parâmetro int, Java chama esse método em vez de autoboxing. Se você quer remover o 2, você pode escrever numbers.remove (new Integer (2)) para forçar o uso da classe wrapper.