jos*_*hlf 7 java methods this nullpointerexception go
在Go中,可以在空指针上调用方法,只要该指针永远不会被解引用:
type empty struct{}
func (e *empty) Allocated() bool { return e != nil }
Run Code Online (Sandbox Code Playgroud)
(对于可运行的代码,请单击此处)
但是,在Java中,调用空指针上的方法,即使该方法从不取消引用任何成员变量,仍会导致空指针异常:
class Test {
public boolean Allocated() { return this != null; }
}
Run Code Online (Sandbox Code Playgroud)
有人知道为什么会出现这种行为吗?它有一些优势吗?思考?
SLa*_*aks 12
这是因为所有Java方法都是虚拟的.
在编写时someInstance.Allocated(),运行时需要检查是否someInstance实际上是覆盖该方法的派生类型.
理论上,这种限制可以放宽final或private方法.
我假设语言设计者选择不一致.(以便删除final不会是一个突破性的变化)
从Java的角度来看,SLaks的答案很好.我对Java没有任何线索,但我知道Go,这是我的答案:
首先nil是NULL指针不一样,有一些根本的区别.
然后,Go中的方法不是类型实例的一部分,而是类型本身,即Go不会将vtable存储在对象内部,就像Java一样:
var e *empty
fmt.Println(e.Allocated())
Run Code Online (Sandbox Code Playgroud)
与...相同(...的语法糖):
var e *empty
fmt.Println((*empty).Allocated(e)) // This is valid code
Run Code Online (Sandbox Code Playgroud)
注意如何Allocated作为成员调用*empty,就像传统的"OOP"语言中的静态方法一样.
实际上,(*empty).Allocated它只是一个带有奇怪符号的函数名称,包括一个点,一个星号和一个parens.
因为接收器只是另一个参数,所以它对nil方法调度机制来说并不重要.
在Go中,可以在空指针上调用方法,只要该指针永远不会被解引用
如果确定你的意思是合法的,那么甚至可以在一个nil值上调用一个方法并取消引用它.编译器不会抱怨 - 你只会遇到运行时恐慌.