Qual é a diferença na memória entre uma variável atribuída a null e uma não atribuída?
Eu sei que há uma diferença no uso, mas qual é a diferença na memória?
Qual é a diferença na memória entre uma variável atribuída a null e uma não atribuída?
Eu sei que há uma diferença no uso, mas qual é a diferença na memória?
Respostas:
Não há diferença entre os dois "na memória".
Na especificação da linguagem Java, 4.12.5. Valores Iniciais das Variáveis :
Toda variável em um programa deve ter um valor antes que seu valor seja usado:
- Cada variável de classe, variável de instância ou componente de matriz é inicializado com um valor padrão quando é criado (§15.9, §15.10.2):
...
- Para todos os tipos de referência (§4.3), o valor padrão é nulo.
...
- Uma variável local (§14.4, §14.14) deve receber explicitamente um valor antes de ser usada, tanto pela inicialização (§14.4) quanto pela atribuição (§15.26), de maneira que possa ser verificada usando as regras para atribuição definida (§ 16 (Cessão Definida)).
As variáveis de referência no nível da classe ou do objeto receberão um valor nulo.
As variáveis de referência no nível do método (pilha) terão um valor não especificado (usando o termo C ++). Na prática, isso geralmente é nulo, mas o padrão não especifica o que está na variável de referência, apenas que ele deve ser atribuído antes do uso. O uso de uma variável de referência na pilha de qualquer outra maneira que não a atribuição como seu primeiro uso resultará em um erro de compilação.
if-thenbloco, o compilador informa que a variável talvez não seja inicializada à frente no código se o thenbloco não for executado. Se você inicializá-lo para nullo código compila. Por que isso, considerando que "uma referência não atribuída explicitamente a um valor terá o valor nulo" ?
nullpois seria um trabalho desnecessário fazê-lo.
Qual é a diferença entre uma variável atribuída a null e outras não atribuídas na memória?
Não existe uma variável não atribuída em Java. Membros de dados da classe que não têm uma atribuição explícita recebem o valor padrão para o tipo, nulo para um objeto ou algo semelhante a 0 para tipos primitivos.
Variáveis locais ficam na pilha. (Locais não primitivos, como MyType footambém vivem na pilha, como referências.) A alocação da pilha é simples. Se um bloco contiver declarações para variáveis locais, o espaço necessário para essas variáveis locais será reservado na pilha. Se valores são atribuídos a essas variáveis locais no ajuste da pilha para acomodar essas variáveis locais é irrelevante.
A razão pela qual isso não importa é se as variáveis locais têm ou não um valor atribuído no momento em que a execução entra no bloco. Uma razão é que o tamanho necessário não muda. As primitivas têm um tamanho fixo e as não primitivas são na verdade referências. (O objeto referenciado reside na pilha e não na pilha.) O segundo motivo é que o uso de uma variável local que não foi atribuída a um valor é um erro de compilação. Isso deixa ao tempo de execução Java a atribuição de algum valor (não necessariamente o padrão) a uma variável local declarada, mas não atribuída.
if-thenbloco, o compilador informa que a variável talvez não seja inicializada à frente no código se o thenbloco não for executado. Se você inicializá-lo para nullo código compila. Por que isso, considerando que "uma referência não atribuída explicitamente a um valor terá o valor nulo" ? Mas ainda não está claro o suficiente para mim. Você poderia explicar em outras palavras?
null. Isso simplifica bastante o desenvolvimento do depurador Java. Mas e se você compilar com a depuração desativada? Agora essa inicialização é um trabalho extra desnecessário. O conteúdo dessa memória é irrelevante porque é sabido que a memória conterá um valor válido no primeiro uso.
Primeiro, não há realmente necessidade de se preocupar com o espaço usado pelas variáveis locais. Em uma linha, eu posso alocar uma matriz de 100.000 números inteiros, que ocuparão mais espaço do que todas as variáveis locais que você jamais usará.
Segundo, seu código é compilado por um compilador que provavelmente será inteligente. Se sua variável não for inicializada, ela não será usada (porque o compilador não permite o uso de variáveis não inicializadas). Mas se você inicializá-lo para zero, ele ainda não será usado! O compilador descobrirá facilmente que ele não é usado e na verdade não usa espaço para a variável. Mesmo se for usado, o compilador descobrirá facilmente que o valor é nulo e usará nil em vez da variável.
Mas terceiro, são todas as micro-otimizações que não ajudarão você a otimizar um programa de forma alguma. Você está tentando salvar quatro ou oito bytes. Concentre-se em economizar megabytes, se quiser salvar alguma coisa.
E, por último, enquanto algumas pessoas afirmam que as variáveis sempre devem ser inicializadas, isso não é verdade em Java. Você só deve definir uma variável para um valor significativo. Digamos que você queira definir uma variável para o nome de uma pessoa, e esqueça de fazer isso em um caminho de código. Se você inicializar cegamente a variável para zero, o compilador não poderá informar. Sem a inicialização, o compilador pode e irá informar sobre seu erro.