O seguinte código gera NullPointerException:
int num = Integer.getInteger("123");
Meu compilador está invocando getIntegerem null, pois é estático? Isso não faz sentido!
O que está acontecendo?
O seguinte código gera NullPointerException:
int num = Integer.getInteger("123");
Meu compilador está invocando getIntegerem null, pois é estático? Isso não faz sentido!
O que está acontecendo?
Respostas:
Existem dois problemas em jogo aqui:
Integer getInteger(String) não faz o que você pensa que faz
nullneste casoIntegerpara intcausa o desempacotamento automático
Integeré null, NullPointerExceptioné lançadoPara analisar (String) "123"a (int) 123, você pode usar por exemplo int Integer.parseInt(String).
Integer Referências APIInteger.getIntegerAqui está o que a documentação tem a dizer sobre o que esse método faz:
public static Integer getInteger(String nm): Determina o valor inteiro da propriedade do sistema com o nome especificado. Se não houver nenhuma propriedade com o nome especificado, se o nome especificado estiver vazio ounull, ou se a propriedade não tiver o formato numérico correto,nullserá retornado.
Em outras palavras, esse método não tem nada a ver com a análise de a Stringpara um int/Integervalor, mas sim com o System.getPropertymétodo.
É certo que isso pode ser uma grande surpresa. É uma pena que a biblioteca tenha surpresas como essa, mas ela ensina uma lição valiosa: sempre consulte a documentação para confirmar o que um método faz.
Coincidentemente, uma variação desse problema foi apresentada em Return of the Puzzlers: Schlock and Awe (TS-5186) , apresentação de Josh Bloch e Neal Gafter na Sessão Técnica JavaOne 2009. Aqui está o slide de conclusão:
A moral
- Métodos estranhos e terríveis se escondem nas bibliotecas
- Alguns têm nomes que parecem inócuos
- Se o seu código funcionar mal
- Certifique-se de chamar os métodos corretos
- Leia a documentação da biblioteca
- Para designers de API
- Não viole o princípio do menor espanto
- Não viole a hierarquia de abstração
- Não use nomes semelhantes para comportamentos totalmente diferentes
Para completar, também existem estes métodos que são análogos a Integer.getInteger:
A outra questão, claro, é como isso NullPointerExceptioné jogado. Para focar neste problema, podemos simplificar o snippet da seguinte maneira:
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
Aqui está uma citação do Effective Java 2nd Edition, Item 49: Prefira tipos primitivos a primitivos em caixa:
Em resumo, use primitivos em vez de primitivos encaixotados sempre que você tiver escolha. Os tipos primitivos são mais simples e rápidos. Se você deve usar primitivas em caixa, tome cuidado! O autoboxing reduz a verbosidade, mas não o perigo, de usar primitivas em caixas. Quando seu programa compara duas primitivas em caixa com o
==operador, ele faz uma comparação de identidade, o que quase certamente não é o que você deseja. Quando seu programa faz cálculos de tipo misto envolvendo primitivos encaixotados e não encaixotados, ele faz o desempacotamento, e quando o seu programa faz o desempacotamento, ele pode lançarNullPointerException. Finalmente, quando seu programa encaixa valores primitivos, isso pode resultar em criações de objetos caras e desnecessárias.
Há lugares onde você não tem escolha a não ser usar primitivos in a box, por exemplo, genéricos, mas caso contrário, você deve considerar seriamente se a decisão de usar primitivos in a box é justificada.
Integer.getInteger(s)é mais ou menos equivalente a Integer.parseInt(System.getProperty(s))? Acho que prefiro o segundo, embora seja mais detalhado, porque destaca o fato de que você está extraindo informações das propriedades do sistema.
Integer.decodevez de Integer.parseInt, que procura um líder 0xou 0para analisar o número como hexadecimal ou octal, respectivamente.
NullPointerException? : programmers.stackexchange.com/questions/158908/…
De http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html :
getInteger 'Determina o valor inteiro da propriedade do sistema com o nome especificado.'
Você quer isso:
Integer.parseInt("123")
Verifique a documentação do método getInteger () . Neste método, o Stringparâmetro é uma propriedade do sistema que determina o valor inteiro da propriedade do sistema com o nome especificado. "123" não é o nome de nenhuma propriedade do sistema, conforme discutido aqui . Se você deseja converter esta String para int, use o método como
int num = Integer.parseInt("123").