Answers:
null是否是任何实例?
不,没有类型null
是instanceof
。
instanceof
RelationalExpression: RelationalExpression instanceof ReferenceType
在运行时,
instanceof
运算符的结果是,true
如果RelationalExpression的值不是null
,并且引用可以强制转换为ReferenceType而不引发ClassCastException
。否则结果为false
。
这意味着对于任何类型的E
和R
,对于任何E o
,在那里o == null
,o instanceof R
永远是false
。
“ null”属于什么集合?
还有一个特殊的null类型,即expression的类型
null
,它没有名称。因为空类型没有名称,所以不可能声明空类型的变量或将其强制转换为空类型。所述null
参考是一个表达式的唯一可能的值无效的类型。该null
参考总是可以被转换为任何引用类型。在实践中,程序员可以忽略null类型,而只是假装这null
只是可以是任何引用类型的特殊文字。
什么是null?
正如上面的JLS引用所言,在实践中,您可以简单地假装它是“仅仅是可以用于任何引用类型的特殊文字”。
在Java中,null == null
(其他语言并不总是这样)。另请注意,根据合同,它还具有以下特殊属性(来自java.lang.Object
):
public boolean equals(Object obj)
对于任何非
null
参考值x
,x.equals(null)
应该return false
。
它也是所有引用类型的默认值(对于具有它们的变量):
- 每个类变量,实例变量或数组组件在创建时均使用默认值初始化:
- 对于所有引用类型,默认值为
null
。
使用方法各不相同。您可以使用它来启用所谓的字段的延迟初始化,在该字段中,字段的初始值null
直到实际使用为止,在该字段中将其替换为“实际”值(计算起来可能会很昂贵)。
还有其他用途。让我们举一个真实的例子java.lang.System
:
public static Console console()
返回:系统控制台(如果有),否则
null
。
这是一个非常常见的使用模式:null
用于表示对象不存在。
这是另一个用法示例,这次来自java.io.BufferedReader
:
public String readLine() throws IOException
返回:
String
包含行内容的A ,不包含任何行终止字符,或者null
是否已到达流的末尾。
因此,在这里,readLine()
将为instanceof String
每一行返回,直到最终返回a null
表示结束。这使您可以按以下方式处理每一行:
String line;
while ((line = reader.readLine()) != null) {
process(line);
}
可以设计API,使终止条件不依赖于readLine()
返回null
,但是可以看到,这种设计具有使事情简洁的好处。请注意,空行没有问题,因为空行"" != null
。
让我们再举一个例子,这次是从java.util.Map<K,V>
:
V get(Object key)
返回指定键所映射的值,或者
null
此映射不包含该键的映射。如果此映射允许
null
值,则返回值null
不一定表示该映射不包含键的映射;否则,返回值为0 。映射也可能将键显式映射到null
。该containsKey
操作可用于区分这两种情况。
在这里,我们开始了解使用null
如何使事情复杂化。第一条语句说,如果键未映射,null
则返回。第二个声明说,即使按键映射,null
可也被退回。
相反,java.util.Hashtable
通过不允许null
键和值来简化事情;其V get(Object key)
,如果返回null
,则明确表示未映射密钥。
您可以通读其余的API,并找到在何处以及如何null
使用它们。请记住,它们并不总是最佳实践示例。
一般来说,null
用作特殊值表示:
它在内存中如何表示?
在Java中?不用担心 最好保持这种方式。
null
好事吗?现在这是主观的。有人说这null
会导致许多程序员可以避免的错误。有人说,在NullPointerException
像Java这样的流行语言中,最好使用它,因为您会因程序员错误而快速失败。有些人避免null
使用Null对象模式等。
它本身是一个巨大的主题,因此最好将其讨论为对另一个问题的解答。
最后,我将引用null
他自己的发明者CAR Hoare(快速成名)的报价:
我称之为我的十亿美元错误。
null
引用是1965年发明的。当时,我正在设计第一个面向对象语言(ALGOL W)的综合类型系统。我的目标是确保所有引用的使用都绝对安全,并由编译器自动执行检查。但是我无法抗拒引入null
引用的诱惑,仅仅是因为它是如此容易实现。这导致了无数的错误,漏洞和系统崩溃,在最近四十年中可能造成十亿美元的痛苦和破坏。
NIL
)于1960年或更早存在。但是我不认为Hoare 确实试图在该报价中主张发明空引用。
null是否是任何实例?
不。这就是为什么所有班级null instanceof X
都会回来。(不要被您可以分配给类型为对象类型的变量这一事实所迷惑。严格来说,分配涉及隐式类型转换;请参见下文。)false
X
null
“ null”属于什么集合?
它是null类型的唯一成员,其中null类型的定义如下:
“还有一个特殊的空类型,即表达式null的类型,它没有名称。因为空类型没有名称,所以不可能声明一个空类型的变量或将其强制转换为空类型。 reference是null类型的表达式的唯一可能的值。null引用始终可以转换为任何引用类型。实际上,程序员可以忽略null类型而只是假装null只是可以是任何类型的特殊文字参考类型。” JLS 4.1
什么是null?
往上看。在某些情况下,null
用于表示“无对象”或“未知”或“不可用”,但是这些含义是特定于应用程序的。
它在内存中如何表示?
那是特定于实现的,您将无法null
在纯Java程序中看到的表示。(但null
在大多数(如果不是全部)Java实现中,它表示为零机器地址/指针。)
什么是null?
没什么
null是否是任何实例?
不,因为它什么都不是,它不可能是任何事物的实例。
null属于哪个集合?
没有任何集合
它在内存中如何表示?
如果某些参考指向它,例如:
Object o=new Object();
堆内存中有一些空间分配给新创建的对象。o将指向内存中分配的空间。
现在 o=null;
这意味着现在o将不再指向对象的存储空间。
字节码表示
Java null
具有直接的JVM支持:用于实现它的三个指令:
aconst_null
:例如将变量设置null
为Object o = null;
ifnull
和ifnonnull
:例如,一个对象比较null
,如if (o == null)
然后,第6章“ Java虚拟机指令集”提到了null
其他指令的影响:它NullPointerException
为许多指令抛出了。
2.4。“引用类型和值”还null
以通用术语提及:
引用值也可以是特殊的空引用,即无对象的引用,此处将以空表示。空引用最初没有运行时类型,但可以强制转换为任何类型。引用类型的默认值为null。
null
是一个特殊值,它不是任何类的实例。以下程序说明了这一点:
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
内容不是的实例String
。
void f(String o)
,则更有意义。
Java中的null与C ++中的nullptr类似/相似。
用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;
}
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");
}
}
}
现在您从上面的代码中了解Java中的null是什么吗?如果没有,那么我建议您学习C / C ++的指针,然后您将理解。
请注意,在C语言中,与C ++语言不同,未定义nullptr,但使用了NULL,也可以在C ++语言中使用NULL,但是在C ++中,nullptr不仅比NULL更可取,因为C中的NULL始终与指针相关,并且因此,在C ++中,后缀“ ptr”附加在单词的末尾,并且所有字母现在都小写,但这并不重要。
在Java中,每个非基本类型类的变量总是引用该类型或继承的对象,并且null是null类对象引用,但不是null指针,因为在Java中没有这样的东西“指针”,而是对class的引用而是使用对象,并且Java中的null与类对象引用有关,因此您也可以将其称为“ nullref”或“ nullrefobj”,但这很长,因此只需将其称为“ null”即可。
在C ++中,可以将指针和nullptr值用于可选成员/变量,即没有值的成员/变量,如果没有值,则等于nullptr,因此可以使用Java中的null。
在我看来,在Java中查看null的一种有趣方式是将其视为不表示没有信息的东西,而仅仅是将其分配给任何类型的引用的文字值。如果考虑是否表示没有信息,那么a1 == a2为true是没有意义的(如果它们都被分配了null值),因为它们实际上可能指向任何对象(我们只是不知道它们应该指向什么对象)...顺便说一下,null == null在Java中返回true。如果java eg例如SQL:1999,则null == null将返回unknown(SQL:1999中的布尔值可以采用三个值:true,false和unknown,但实际上,unreal在实际系统中实现为null)... http://en.wikipedia.org/wiki/SQL
简短而准确的答案,可以从JLS正式回答您的所有问题:
3.10.7。空字面量
空类型具有一个值,即空引用,由空文字空值表示,由ASCII字符组成。
空文字始终是空类型。
仅分配分配给null的类型的引用。您没有为参考分配任何值(对象)。这种分配是特定于JVM的,它将获取多少参考以及将在哪个内存区域中分配参考。