未调用函数中的Clojure(让[frame(java.awt.frame.)])导致awt启动
在阅读Clojure书籍的过程中,我成功地定义了一个函数,当调用该函数时,它将创建并绘制一个java.awt.Frame未调用函数中的Clojure(让[frame(java.awt.frame.)])导致awt启动,clojure,awt,leiningen,Clojure,Awt,Leiningen,在阅读Clojure书籍的过程中,我成功地定义了一个函数,当调用该函数时,它将创建并绘制一个java.awt.Frame (defn draw-frame [f x y] (let [frame (java.awt.Frame.)])) 但是,在新的空Leiningen项目中,只需在新的Leiningen REPL中定义函数,AWT框架就会启动。我这样说,因为输入上述函数定义会导致一个新的OSX“窗口”以“主”菜单选项打开。如果关闭此窗口,clojure REPL将退出 否则,函数将继续按
(defn draw-frame [f x y]
(let [frame (java.awt.Frame.)]))
但是,在新的空Leiningen项目中,只需在新的Leiningen REPL中定义函数,AWT框架就会启动。我这样说,因为输入上述函数定义会导致一个新的OSX“窗口”以“主”菜单选项打开。如果关闭此窗口,clojure REPL将退出
否则,函数将继续按预期运行,但我很想理解为什么会发生这种情况——在Java中创建类似的函数(引用但不实例化Java.awt.Frame)不会表现出相同的症状。通过
rt.jar
进行一些探索,我能够找到它
java.awt.Frame的静态初始值设定项[1]如下所示:
0: iconst_0
1: putstatic #20 // Field nameCounter:I
4: invokestatic #114 // Method java/awt/Toolkit.loadLibraries:()V
7: invokestatic #115 // Method java/awt/GraphicsEnvironment.isHeadless:()Z
10: ifne 16
13: invokestatic #116 // Method initIDs:()V
16: new #117 // class java/awt/Frame$1
19: dup
20: invokespecial #118 // Method java/awt/Frame$1."<init>":()V
23: invokestatic #119 // Method sun/awt/AWTAccessor.setFrameAccessor:(Lsun/awt/AWTAccessor$FrameAccessor;)V
26: return
0: getstatic #84 // Field loaded:Z
3: ifne 23
6: new #85 // class sun/security/action/LoadLibraryAction
9: dup
10: ldc #86 // String awt
12: invokespecial #87 // Method sun/security/action/LoadLibraryAction."<init>":(Ljava/lang/String;)V
15: invokestatic #32 // Method java/security/AccessController.doPrivileged:(Ljava/security/PrivilegedAction;)Ljava/lang/Object;
18: pop
19: iconst_1
20: putstatic #84 // Field loaded:Z
23: return
(doto (sun.security.action.LoadLibraryAction. "awt")
(java.security.AccessController/doPrivileged))
loadLibraries
似乎很有趣,因此反汇编看起来像:
0: iconst_0
1: putstatic #20 // Field nameCounter:I
4: invokestatic #114 // Method java/awt/Toolkit.loadLibraries:()V
7: invokestatic #115 // Method java/awt/GraphicsEnvironment.isHeadless:()Z
10: ifne 16
13: invokestatic #116 // Method initIDs:()V
16: new #117 // class java/awt/Frame$1
19: dup
20: invokespecial #118 // Method java/awt/Frame$1."<init>":()V
23: invokestatic #119 // Method sun/awt/AWTAccessor.setFrameAccessor:(Lsun/awt/AWTAccessor$FrameAccessor;)V
26: return
0: getstatic #84 // Field loaded:Z
3: ifne 23
6: new #85 // class sun/security/action/LoadLibraryAction
9: dup
10: ldc #86 // String awt
12: invokespecial #87 // Method sun/security/action/LoadLibraryAction."<init>":(Ljava/lang/String;)V
15: invokestatic #32 // Method java/security/AccessController.doPrivileged:(Ljava/security/PrivilegedAction;)Ljava/lang/Object;
18: pop
19: iconst_1
20: putstatic #84 // Field loaded:Z
23: return
(doto (sun.security.action.LoadLibraryAction. "awt")
(java.security.AccessController/doPrivileged))
运行它会导致弹出相同的应用程序,因此我怀疑本机库中有导致它的初始值设定项代码。不幸的是,我不想投入到真正的拆卸中,所以其他人将不得不从这一点上找出它
[1] :我解包rt.jar,然后使用
javap-p-cfoo.class
来查看这一点。一个更简单的复制方法就是在REPL处键入java.awt.Frame
。这提示一旦加载任何与awt相关的内容,就会出现一个应用程序窗口,但我还没有找到一个更权威的信息来源;我试图在Ubuntu上复制,但窗口没有出现。