我正在慢慢地完成Bruce Eckel的Thinking in Java第4版,以下问题让我感到难过:
使用finalize()方法创建一个打印消息的类.在main()中,创建一个类的对象.修改上一个练习,以便始终调用finalize().
这是我编码的:
public class Horse {
boolean inStable;
Horse(boolean in){
inStable = in;
}
public void finalize(){
if (!inStable) System.out.print("Error: A horse is out of its stable!");
}
}
public class MainWindow {
public static void main(String[] args) {
Horse h = new Horse(false);
h = new Horse(true);
System.gc();
}
}
Run Code Online (Sandbox Code Playgroud)
它创建一个Horse布尔值inStable设置为的新对象false.现在,在该finalize()方法中,它检查是否inStable是false.如果是,则打印一条消息.
不幸的是,没有打印消息.由于条件评估为true,我的猜测是finalize()首先没有被调用.我已经多次运行该程序,并且已经看到错误消息只打印了几次.我的印象是,当System.gc()调用时,垃圾收集器将收集任何未引用的对象.
谷歌搜索一个正确的答案给了我这个链接,它提供了更详细,更复杂的代码.它采用了我以前从未见过的方法,如 …
JVM 规范 ( 5.4.3.3 ) 描述了如何为方法引用完成方法解析。如果在类或其超类中找不到方法,它会尝试在超接口中找到方法。
这是什么原因?由超接口声明的方法不会作为接口方法 ref 而不是方法 ref 列在常量池中吗?
我的理解是方法引用用于invokevirtual操作,而接口方法引用用于invokeinterface操作。我不知道如何使用invokevirtual <methodref>.
假设我有一个模块A,具有以下接口和实现文件:
(* a.mli *)
module type A_SIG =
sig
val f: int -> int
...
end
(* a.ml *)
module A : A_SIG =
struct
let f x = x + 1
...
end
Run Code Online (Sandbox Code Playgroud)
编译a.mli后跟a.ml失败,错误Unbound module type A_SIG.复制实现文件中的整个签名可以修复它.
为什么会这样?似乎以下工作在SML中:
(* a.sig *)
signature A_SIG =
sig
val f: int -> int
...
end
(* a.sml *)
structure A : A_SIG =
struct
fun f x = x+1
...
end
Run Code Online (Sandbox Code Playgroud)
我看过这个类似的帖子,但我的回答并不清楚.