O que é null
?
É null
uma instância de alguma coisa?
A que conjunto null
pertence?
Como isso é representado na memória?
O que é null
?
É null
uma instância de alguma coisa?
A que conjunto null
pertence?
Como isso é representado na memória?
Respostas:
Null é uma instância de alguma coisa?
Não, não existe um tipo que null
seja um instanceof
.
instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
No tempo de execução, o resultado do
instanceof
operador étrue
se o valor da RelationalExpression não fornull
e a referência poderá ser convertida para o ReferenceType sem gerar aClassCastException
. Caso contrário, o resultado éfalse
.
Isso significa que para qualquer tipo E
e R
, para qualquer E o
, onde o == null
, o instanceof R
é sempre false
.
A que conjunto pertence 'null'?
Há também um tipo nulo especial , o tipo da expressão
null
, que não tem nome. Como o tipo nulo não tem nome, é impossível declarar uma variável do tipo nulo ou converter para o tipo nulo . Anull
referência é o único valor possível de uma expressão do tipo nulo . Anull
referência sempre pode ser convertida para qualquer tipo de referência. Na prática, o programador pode ignorar o tipo nulo e apenas fingir quenull
é apenas um literal especial que pode ser de qualquer tipo de referência.
O que é nulo?
Como a citação JLS acima diz, na prática você pode simplesmente fingir que é "apenas um literal especial que pode ser de qualquer tipo de referência".
Em Java, null == null
(isso nem sempre é o caso em outras linguagens). Observe também que, por contrato, ele também possui esta propriedade especial (de java.lang.Object
):
public boolean equals(Object obj)
Para qualquer
null
valor que não seja de referênciax
,x.equals(null)
deveriareturn false
.
Também é o valor padrão (para variáveis que os possuem) para todos os tipos de referência:
- Cada variável de classe, variável de instância ou componente de matriz é inicializado com um valor padrão quando é criado:
- Para todos os tipos de referência, o valor padrão é
null
.
Como isso é usado varia. Você pode usá-lo para ativar o que é chamado de inicialização lenta de campos, onde um campo teria seu valor inicial null
até que seja realmente usado, onde será substituído pelo valor "real" (que pode ser caro para calcular).
Existem também outros usos. Vamos dar um exemplo real de java.lang.System
:
public static Console console()
Retorna : o console do sistema, se houver, caso contrário
null
.
Este é um padrão de uso muito comum: null
é usado para denotar a inexistência de um objeto.
Aqui está outro exemplo de uso, desta vez de java.io.BufferedReader
:
public String readLine() throws IOException
Retorna : A que
String
contém o conteúdo da linha, sem incluir nenhum caractere de terminação de linha ounull
se o final do fluxo foi atingido.
Então, aqui, readLine()
retornaria instanceof String
para cada linha, até que finalmente retorne a null
para significar o fim. Isso permite que você processe cada linha da seguinte maneira:
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
Pode-se projetar a API para que a condição de terminação não dependa do readLine()
retorno null
, mas pode-se ver que esse design tem o benefício de tornar as coisas concisas. Observe que não há problema com linhas vazias, porque uma linha vazia "" != null
.
Vamos dar outro exemplo, desta vez de java.util.Map<K,V>
:
V get(Object key)
Retorna o valor para o qual a chave especificada está mapeada ou
null
se este mapa não contiver mapeamento para a chave.Se este mapa permitir
null
valores, um valor de retornonull
não indica necessariamente que o mapa não contém mapeamento para a chave; também é possível que o mapa mapeie explicitamente a chavenull
. AcontainsKey
operação pode ser usada para distinguir esses dois casos.
Aqui começamos a ver como o uso null
pode complicar as coisas. A primeira instrução diz que, se a chave não estiver mapeada, null
será retornada. A segunda declaração diz que, mesmo que a chave esteja mapeada, ela tambémnull
pode ser retornada.
Por outro lado, java.util.Hashtable
simplifica as coisas, não permitindo null
chaves e valores; isso V get(Object key)
, se retornar null
, significa sem ambiguidade que a chave não está mapeada.
Você pode ler o restante das APIs e descobrir onde e como null
é usado. Lembre-se de que eles nem sempre são os exemplos de melhores práticas .
De um modo geral, null
são usados como um valor especial para significar:
Como isso é representado na memória?
Em Java? Não é da sua conta. E é melhor mantê-lo assim.
null
uma coisa boa?Agora isso é subjetivo limítrofe. Algumas pessoas dizem que isso null
causa muitos erros de programador que poderiam ter sido evitados. Alguns dizem que em uma linguagem que pega NullPointerException
como Java, é bom usá-lo porque você irá falhar rapidamente em erros de programador. Algumas pessoas evitam null
usar o padrão de objeto Nulo , etc.
Este é um tópico enorme por si só, por isso é melhor discutido como resposta a outra pergunta.
Terminarei isso com uma citação do próprio inventor null
, CAR Hoare (de fama de quicksort):
Eu chamo de erro do meu bilhão de dólares. Foi a invenção da
null
referência em 1965. Naquela época, eu estava projetando o primeiro sistema abrangente de tipos para referências em uma linguagem orientada a objetos (ALGOL W). Meu objetivo era garantir que todo o uso de referências fosse absolutamente seguro, com a verificação realizada automaticamente pelo compilador. Mas não pude resistir à tentação de fazer umanull
referência, simplesmente porque era muito fácil de implementar. Isso levou a inúmeros erros, vulnerabilidades e falhas no sistema, que provavelmente causaram um bilhão de dólares de dor e danos nos últimos quarenta anos.
O vídeo desta apresentação é mais profundo; é um relógio recomendado.
NIL
) em 1960, e provavelmente antes. Mas não acho que Hoare esteja realmente tentando reivindicar a invenção de referências nulas nessa citação.
Null é uma instância de alguma coisa?
Não. É por isso null instanceof X
que retornará false
para todas as classes X
. (Não se deixe enganar pelo fato de poder atribuir null
a uma variável cujo tipo é um tipo de objeto. Estritamente falando, a atribuição envolve uma conversão implícita de tipo; veja abaixo.)
A que conjunto pertence 'null'?
É o primeiro e único membro do tipo nulo, em que o tipo nulo é definido da seguinte maneira:
"Também existe um tipo nulo especial, o tipo da expressão nulo, que não tem nome. Como o tipo nulo não tem nome, é impossível declarar uma variável do tipo nulo ou converter para o tipo nulo. reference é o único valor possível de uma expressão do tipo nulo.A referência nula sempre pode ser convertida para qualquer tipo de referência.Na prática, o programador pode ignorar o tipo nulo e apenas fingir que nulo é apenas um literal especial que pode ser de qualquer tipo tipo de referência." JLS 4.1
O que é nulo?
Veja acima. Em alguns contextos, null
é usado para denotar "nenhum objeto" ou "desconhecido" ou "indisponível", mas esses significados são específicos de aplicativos.
Como isso é representado na memória?
Isso é específico da implementação e você não poderá ver a representação null
em um programa Java puro. (Mas null
é representado como um endereço / ponteiro zero da máquina na maioria, se não em todas as implementações de Java.)
O que é nulo?
Não é nada.
Null é uma instância de alguma coisa?
Não, pois não é nada. Não pode ser instância de nada.
A que conjunto pertence o nulo?
Nenhum conjunto
Como isso é representado na memória?
Se algumas referências apontarem para ele, como:
Object o=new Object();
Na memória de heap, algum espaço atribuído ao novo objeto criado. E o apontará para o espaço atribuído na memória.
Agora o=null;
Isso significa que agora o não apontará para esse espaço de memória do objeto.
A palavra-chave nula é um literal que representa uma referência nula, que não se refere a nenhum objeto . null é o valor padrão das variáveis do tipo de referência.
Talvez também dê uma olhada
Nulo em Java (tm)
Em C e C ++, "NULL" é uma constante definida em um arquivo de cabeçalho, com um valor como:
0
ou:
0L
ou:
((void*)0)
dependendo das opções do compilador e do modelo de memória. NULL não é, estritamente falando, parte do próprio C / C ++.
No Java (tm), "null" não é uma palavra-chave, mas um literal especial do tipo nulo. Pode ser convertido para qualquer tipo de referência, mas não para qualquer tipo primitivo, como int ou booleano. O literal nulo não necessariamente tem valor zero. E é impossível converter para o tipo nulo ou declarar uma variável desse tipo.
Representação de bytecode
O Java null
possui suporte direto à JVM: três instruções são usadas para implementá-lo:
aconst_null
: por exemplo, para definir uma variável null
como emObject o = null;
ifnull
e ifnonnull
: por exemplo, para comparar um objeto null
como emif (o == null)
O capítulo 6 "O conjunto de instruções da Java Virtual Machine" menciona os efeitos de null
outras instruções: lança um NullPointerException
para muitos deles.
2.4 "Tipos e valores de referência" também menciona null
em termos genéricos:
Um valor de referência também pode ser a referência nula especial, uma referência a nenhum objeto, que será indicado aqui por nulo. A referência nula inicialmente não tem tipo de tempo de execução, mas pode ser convertida para qualquer tipo. O valor padrão de um tipo de referência é nulo.
null
é um valor especial, não é instância de nada. Por uma razão óbvia, não pode ser instanceof
nada.
null
é um valor especial que não é uma instância de nenhuma classe. Isso é ilustrado pelo seguinte programa:
public class X {
void f(Object o)
{
System.out.println(o instanceof String); // Output is "false"
}
public static void main(String[] args) {
new X().f(null);
}
}
null
não é uma instância de String
.
void f(String o)
, faria mais sentido.
null em Java é semelhante / semelhante a nullptr em C ++.
Programa em C ++:
class Point
{
private:
int x;
int y;
public:
Point(int ix, int iy)
{
x = ix;
y = iy;
}
void print() { std::cout << '(' << x << ',' << y << ')'; }
};
int main()
{
Point* p = new Point(3,5);
if (p != nullptr)
{
p->print();
p = nullptr;
}
else
{
std::cout << "p is null" << std::endl;
}
return 0;
}
Mesmo programa em Java:
public class Point {
private int x;
private int y;
public Point(int ix, int iy) {
x = ix;
y = iy;
}
public void print() { System.out.print("(" + x + "," + y + ")"); }
}
class Program
{
public static void main(String[] args) {
Point p = new Point(3,5);
if (p != null)
{
p.print();
p = null;
}
else
{
System.out.println("p is null");
}
}
}
Agora você entende pelos códigos acima o que é nulo em Java? Se não, recomendo que você aprenda ponteiros em C / C ++ e então entenderá.
Observe que em C, ao contrário de C ++, nullptr é indefinido, mas NULL é usado em vez disso, o que também pode ser usado em C ++, mas em C ++ o nullptr é mais preferível do que apenas NULL, porque o NULL em C está sempre relacionado a ponteiros e isso é então, em C ++, o sufixo "ptr" foi acrescentado ao final da palavra e agora todas as letras são minúsculas, mas isso é menos importante.
Em Java, cada variável da classe de tipo não primitiva sempre é referência a objeto desse tipo ou herdada e null é referência de objeto de classe nula, mas não ponteiro nulo, porque em Java não existe tal coisa "ponteiro", mas referências a classe objetos são usados e nulo em Java está relacionado às referências a objetos de classe; portanto, você também pode chamá-lo como "nullref" ou "nullrefobj", mas como é longo, basta chamá-lo de "nulo".
Em C ++, você pode usar ponteiros e o valor nullptr para membros / variáveis opcionais , ou seja, membro / variável que não tem valor e, se não tiver valor, será igual a nullptr; portanto, como nulo em Java pode ser usado, por exemplo.
Existem duas categorias principais de tipos em Java: primitivo e referência . Variáveis declaradas de um tipo primitivo armazenam valores; variáveis declaradas de um tipo de referência armazenam referências.
String x = null;
Nesse caso, a instrução de inicialização declara as variáveis "x". "X" armazena a referência de sequência. Aqui é nulo . Antes de tudo, null não é uma instância de objeto válida, portanto, não há memória alocada para ele. É simplesmente um valor que indica que a referência do objeto não está se referindo atualmente a um objeto.
Uma maneira interessante de ver nulo em java na minha opinião é vê-lo como algo que NÃO denota falta de informação, mas simplesmente como um valor literal que pode ser atribuído a uma referência de qualquer tipo. Se você pensar sobre isso, se denotou ausência de informações, então a1 == a2 é verdadeiro não faz sentido (no caso de ambos terem sido atribuídos a um valor nulo), pois eles poderiam realmente estar apontando para QUALQUER objeto (simplesmente não sei para quais objetos eles devem estar apontando) ... A propósito, null == null retorna true em java. Se java, por exemplo, seria como SQL: 1999, então null == null retornaria desconhecido (um valor booleano no SQL: 1999 pode assumir três valores: verdadeiro, falso e desconhecido, mas na prática o desconhecido é implementado como nulo em sistemas reais) ... http://en.wikipedia.org/wiki/SQL
Resposta curta e precisa que responde formalmente a todas as suas perguntas da JLS:
3.10.7 O Literal Nulo
O tipo nulo possui um valor, a referência nula, representada pelo literal nulo nulo, formado a partir de caracteres ASCII.
Um literal nulo é sempre do tipo nulo.
Apenas uma referência do tipo que é atribuída a null é alocada. Você não atribui nenhum valor (objeto) à referência. Essa alocação é específica para a JVM quanta referência será necessária e em qual área de memória será alocada.