Referências a objetos inteiros em Java
Não há ponteiro em Java, mas também há conceitos de referência. O que queremos falar aqui é se o número inteiro é o mesmo objeto.
1. Vamos olhar para um pedaço de código primeiro:
public static void main (String [] args) {Inteiro A1 = 100; Inteiro b1 = a1; // o outro também pode ser b1 = 100 campo de campo = nulo; tente {field = a1.getclass (). getDeclaredfield ("value"); } catch (nosuchfieldException e) {// TODO BLOCO DE CATAGEM AUTOGERATION E.PRINTSTACKTRACE (); } Catch (SegurançaException e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } field.setAccessible (true); tente {field.set (a1, 5000); } catch (ilegalArgumentException e) {// TODO BLOCO DE CATAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } catch (ilegalAccessException e) {// TODO BLOCO DE CATAGEM AUTOGERATO E.PRINTSTACKTRACE (); } System.out.println ("b1 ="+b1); Inteiro C1 = 100; System.out.println ("c1 ="+c1); } resultado:
B1 = 5000
C1 = 5000
Do exposto, antes de tudo, quero explicar algumas coisas aqui.
1) Para o número inteiro, o número inteiro entre -128-127 foi inicializado e colocado em integgercache. Se estiver embalado, o objeto será retirado dele.
2) B1 = A1 é uma atribuição numérica ou o mesmo objeto? Isso pode ser visto dos resultados que B1 e A1 apontam para o mesmo objeto, não o mesmo valor numérico
3) C1 = 100 significa que, para os valores entre -128-127, todos os objetos obtidos do Integercache. Depois que o objeto inteiro correspondente a 100 for alterado, o empacotamento subsequente de 100 será alterado. Porque ao obter objetos no cache, o índice de matriz é usado, não são usadas comparações numéricas.
No entanto, modificar esse cache será mais perigoso, então não se importe. Quem sabe qual pacote de jar ou plataforma para embalar 100 yuan, mas o resultado não é 100 yuan, e ele falhará naquele momento.
2. Através da descrição acima, qual é a resposta se for alterada para este
public static void main (String [] args) {Inteiro A1 = 200; Inteiro B1 = A1; Campo de campo = nulo; tente {field = a1.getclass (). getDeclaredfield ("value"); } catch (nosuchfieldException e) {// TODO BLOCO DE CATAGEM AUTOGERATION E.PRINTSTACKTRACE (); } Catch (SegurançaException e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } field.setAccessible (true); tente {field.set (a1, 5000); } catch (ilegalArgumentException e) {// TODO BLOCO DE CATAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } catch (ilegalAccessException e) {// TODO BLOCO DE CATAGEM AUTOGERATO E.PRINTSTACKTRACE (); } System.out.println ("b1 ="+b1); Inteiro C1 = 200; System.out.println ("c1 ="+c1); } 3. Em seguida, mude
public static void main (string [] args) {inteiro a1 = new Integer (100); Inteiro B1 = A1; Campo de campo = nulo; tente {field = a1.getclass (). getDeclaredfield ("value"); } catch (nosuchfieldException e) {// TODO BLOCO DE CATAGEM AUTOGERATION E.PRINTSTACKTRACE (); } Catch (SegurançaException e) {// TODO BLOCO DE CAPAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } field.setAccessible (true); tente {field.set (a1, 5000); } catch (ilegalArgumentException e) {// TODO BLOCO DE CATAGEM AUTOMENTADO E.PRINTSTACKTRACE (); } catch (ilegalAccessException e) {// TODO BLOCO DE CATAGEM AUTOGERATO E.PRINTSTACKTRACE (); } System.out.println ("b1 ="+b1); Inteiro C1 = 100; System.out.println ("c1 ="+c1); } Qual é a resposta? Para novas operações, os objetos não são encaixotados, mas são gerados na pilha.
Não é difícil entender se você entende o boxe, o cache e a citação. Você pode experimentar você mesmo.
Vamos obter algum conhecimento básico primeiro
Correspondência de tipos básicos e classes de invólucro byte byte curto curto int inteiro longa flutuação longa caráter duplo duplo personagem boolean boolean
A correspondência entre os tipos de dados básicos nos oito oito acima é apenas um caractere inteiro. As duas mudanças são significativas e o restante está apenas convertendo a primeira letra em minúsculas.
Vamos aprender sobre os novos recursos do JDK5: embalagem automática e unboxing
Boxe automático: converta tipos básicos em tipos de classe de embalagem
Unboxing automático: converta o tipo de classe de wrapper no tipo básico
public class Demo_Integer {public static void main (string [] args) {// antes de jdk1.5 int a = 100; Inteiro A1 = Novo Inteiro (A); // Enrole o tipo de dados básico em um objeto, caixa int b = a1.IntValue (); // converte o objeto para o tipo de dados básico e unbox // após jdk1.5 int x = 100; Inteiro x1 = x; // Caixa automaticamente, converta o tipo de dados básico em um objeto int y = x1 + x; // UNBOX automaticamente, converta o objeto para o tipo de dados básico}}Coisas a serem observadas
public class Demo_Integer {public static void main (String [] args) {Integer a = null; int b = a + 100; // A camada inferior do Unboxing automática chamará A.IntValue (), A é nulo, e A naturalmente lançará o NullPointerException System.out.println (b); }}Perguntas da entrevista
classe pública Demo_Integer {public static void main (string [] args) {Integer i1 = new Integer (97); Número inteiro i2 = novo número inteiro (97); System.out.println (i1 == i2); System.out.println (i1.equals (i2)); System.out.println ("-----------"); Inteiro I3 = New Integer (197); Inteiro I4 = New Integer (197); System.out.println (i3 == i4); System.out.println (i3.equals (i4)); System.out.println ("--------------"); }}Saída: false true --------------------------------------
razão:
O novo é abrir espaço na memória da heap, e o valor do endereço de comparação natural (==) é falso.
Como o número inteiro reescreve o método igual, a saída igual é verdadeira.
Você pode sentir que é muito simples e não tem conteúdo técnico, porque o acima não é o ponto, olhe para o código abaixo
public class Demo_Integer {public static void main (String [] args) {Integer i1 = 127; Número inteiro i2 = 127; System.out.println (i1 == i2); System.out.println (i1.equals (i2)); System.out.println ("------------"); Número inteiro i3 = 128; Número inteiro i4 = 128; System.out.println (i3 == i4); System.out.println (i3.equals (i4)); System.out.println ("-------------"); }}Saída: true true --------------------------------------------
razão:
Por que dois objetos quando int é maior que 127? O número 127 se sente muito familiar?
-128 a 127 são o intervalo de valor de byte. Se estiver dentro desse intervalo de valor, o boxe automático não criará um novo objeto e obtenha -o do pool constante
Se o intervalo de valor de byte for excedido, um novo objeto será criado.
Embale automaticamente a camada subjacente e ligue para o método valueof (), análise simples do código -fonte (JDK1.8):
A classe final pública Integer estende o número implementa comparável <TEGER> {public estático Valueof (int i) {// Quando i> = -128 e i <= 127, o objeto no buffer será diretamente recuperado se (i> = integgercache.low & i <= Integercache.HighLeLELTELTEGERCATECATECATECATECATECATECATECATECATECATECATECATECATECATECATECATECATECATECATECATECATE; Retorne o novo número inteiro (i); // Se o intervalo de valor de bytes exceder o intervalo, ele será criado na memória da heap} // A classe interna atua como uma classe estática privada buffer integgercache {estática final int baixo = -128; estático final int alto; Cache inteiro final estático []; estático {// Alto valor pode ser configurado pela propriedade int h = 127; String integegercacheHighPropValue = Sun.misc.vm.getSavedProperty ("java.lang.integer.integercache.high"); if (integercacheHighPropValue! = null) {try {int i = parseInt (integercacheHighPropValue); i = math.max (i, 127); // O tamanho máximo da matriz é inteiro.max_value h = math.min (i, integer.max_value -(-low) -1); } catch (númeroFormatexception nfe) {// Se a propriedade não puder ser analisada em um int, ignore -o. }} alta = h; cache = novo número inteiro [(alto - baixo) + 1]; int j = baixo; for (int k = 0; k <cache.length; k ++) cache [k] = novo número inteiro (j ++); // intervalo [-128, 127] deve ser internalizado (JLS7 5.1.7) assert integercache.high> = 127; } private integercache () {}}} 8 tipos básicos de classes de embalagem e pools de objetos
A maioria dos tipos básicos de classes de invólucro na Java implementa a tecnologia constante de pool. Essas classes são bytes, curtas, inteiras, longas, personagens, booleanas e os outros dois tipos de classes de wrapper com número de ponto flutuante não são implementados. Além disso, as cinco classes de invólucro inteiro de byte, curto, inteiro e longo, caráter só podem usar o pool de objetos quando o valor correspondente for menor ou igual a 127, ou seja, o objeto não é responsável por criar e gerenciar objetos dessas classes maiores que 127.
Conhecimento estendido
Na especificação da JVM, cada tipo tem seu próprio pool constante. Um pool constante é uma coleção ordenada de constantes usadas por um determinado tipo, incluindo constantes diretas (tipos primitivos, cordas) e referências simbólicas a outros tipos, campos e métodos. A razão pela qual é referência simbólica, em vez de especificar diretamente outros tipos no momento da compilação, é porque o Java está dinamicamente ligado e somente em tempo de execução as instâncias específicas de dependência do tipo são determinadas de acordo com certas regras. Esta é a base para o Java implementar o polimorfismo.
Na JVM, todo o ciclo de vida de uma classe começa por ser carregado na memória da máquina virtual e até que seja descarregada da memória. Seu ciclo de vida inteiro inclui: carregamento, verificação, preparação, análise, inicialização, uso e descarregamento. O estágio de análise é o processo da máquina virtual que substitui as referências de símbolo no pool constante por referências diretas.
Resumir
O acima é o conteúdo inteiro deste artigo. Espero que o conteúdo deste artigo tenha certo valor de referência para o estudo ou trabalho de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar. Obrigado pelo seu apoio ao wulin.com.