static
membros ( static
campos ou static
métodos) em Java são associados a suas respectivas classes, e não aos objetos dessa classe. O código a seguir tenta acessar um campo estático em uma null
referência.
public class Main
{
private static final int value = 10;
public Main getNull()
{
return null;
}
public static void main(String[] args)
{
Main main=new Main();
System.out.println("value = "+main.getNull().value);
}
}
Embora main.getNull()
retorne null
, ele funciona e exibe value = 10
. Como funciona esse código?
Main main = null; main.getNull().value
.new Thread[]{}[-1].sleep(10);
onde sleep () é um método estático. Isso costumava ser bem-sucedido em algumas versões anteriores do Java.Respostas:
Esse comportamento é especificado na Especificação da linguagem Java :
Em mais detalhes, uma avaliação de campo estática , como
Primary.staticField
funciona da seguinte maneira (grifo meu) - no seu casoPrimary = main.getNull()
:fonte
Porque, como você disse, os campos estáticos não estão associados a uma instância.
A capacidade de acessar campos estáticos de uma referência de instância (como você está fazendo) é meramente um açúcar sintático e não tem nenhum significado adicional.
Seu código compila para
fonte
Sempre que você acessa uma variável ou método estático com objetos em tempo de compilação, ele é convertido para o nome da classe. por exemplo:
Irá imprimir o valor do valor da variável estática porque em tempo de compilação será convertido para
Prova:
baixe o descompilador e descompile seu arquivo .class para o arquivo .java e você poderá ver todos os métodos estáticos ou o nome do objeto referenciado à variável é automaticamente substituído pelo nome da classe.
fonte
Acessar um
static
membro com o nome da classe é legal, mas não foi escrito que não se pode acessar ostatic
membro usando a variável de referência do objeto. Então funciona aqui.Uma
null
variável de referência de objeto tem permissão para acessar umastatic
variável de classe sem lançar uma exceção em tempo de compilação ou execução.fonte
A variável estática e o método sempre pertencem à classe. Portanto, sempre que criamos qualquer objeto, apenas variáveis e métodos não estáticos vão para o heap junto com o objeto, mas estático reside na área de método com a classe. É por isso que, sempre que tentamos acessar uma variável estática ou método, ele é convertido em variável de ponto de nome de classe ou nome de método.
Por favor, consulte o link abaixo para mais detalhes.
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
fonte