我正在为Java Runtime Environment编辑java.lang.Object。我意识到可能有更好的方法来做我想要的,但这不是我的问题。
基本上我已经为java.lang.Object添加了一个构造函数,每次创建一个对象时都会调用它。我正在等待某个类加载如此:
public Object() {
if (hookEnabled) {
hookEnabled = false;
objectCount++;
if (objectCount > objectStartCount) {
if (this.getClass() != null) {
String name = this.getClass().getName();
if ((!name.startsWith("java.")) && (!name.startsWith("javax.")) && (!name.startsWith("launcher.")) && (!name.startsWith("sunw.")) && (!name.startsWith("com.sun.")) && (!name.startsWith("sun.")) && (!name.startsWith("org.xml.")) && (!name.startsWith("org.w3c.")) && (!name.startsWith("org.omg.")) && (!name.startsWith("org.ietf."))) {
if (!hasHooked) {
hasHooked = true;
//startup beep
java.awt.Toolkit.getDefaultToolkit().beep();
//load interface
javax.swing.JFrame frame = new javax.swing.JFrame("");
frame.setBounds(0, 0, 400, 400);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
}
}
}
hookEnabled = true;
}
}
这很好用。它为JVM运行的任何应用程序添加了一个窗口。
但是,当通过将JFrame代码移动到单独的类中进行简单更改并调用该调用时,JVM只会崩溃:
public Object() {
if (hookEnabled) {
hookEnabled = false;
objectCount++;
if (objectCount > objectStartCount) {
if (this.getClass() != null) {
String name = this.getClass().getName();
if ((!name.startsWith("java.")) && (!name.startsWith("javax.")) && (!name.startsWith("launcher.")) && (!name.startsWith("sunw.")) && (!name.startsWith("com.sun.")) && (!name.startsWith("sun.")) && (!name.startsWith("org.xml.")) && (!name.startsWith("org.w3c.")) && (!name.startsWith("org.omg.")) && (!name.startsWith("org.ietf."))) {
if (!hasHooked) {
hasHooked = true;
(new tvmh.DFVMH()).setup();
}
}
}
}
hookEnabled = true;
}
}
-
package tvmh;
public class DFVMH {
public void setup() {
//startup beep
java.awt.Toolkit.getDefaultToolkit().beep();
//load interface
javax.swing.JFrame frame = new javax.swing.JFrame("");
frame.setBounds(0, 0, 400, 400);
frame.setAlwaysOnTop(true);
frame.setVisible(true);
}
}
当我尝试创建java.util.Timer对象时也会发生同样的情况。
有趣的是,如果我将DFVMH作为java.lang.Object本身的内联类(内部类),上面的工作就可以了。
有谁能告诉我为什么会发生这种行为?有没有办法安全地调用这样的自定义类?
答案 0 :(得分:3)
像这样摆弄JVM的内部是非常危险的。 JVM的低级别存在各种隐藏的依赖关系,可能会破坏。 JVM引导程序是一个非常精细的过程。
例如,您发现崩溃而非StackOverflowError
的最可能原因是您的更改已破坏所有对象构造...包括构造错误对象。
我怀疑你的守卫代码是无效的,因为this.getClass().getName()
可能导致创建一个String对象。因此致命的递归发生在你接近警卫之前。
(顺便提一下,你的hasHooked
标志会引入竞争条件。)
我的建议是“不要这样做!”。
答案 1 :(得分:1)
'崩溃'是什么意思?
不是StackOverflowException
吗?你的new tvmh.DFVMH()
实际上也是一个构造函数。所以它贯穿你的'overriden'Object构造函数。
如果你已经这样玩了,那么如何添加tvmh.DFVMH
来停止包/类列表呢?
答案 2 :(得分:1)
快速思考:new tvmh.DFVHM()
成为一个新对象,也派生自java.lang.Object,这意味着您的自定义构造函数代码将在第一个完成之前再次运行。我猜测“hasHooked”应该防范这一点,但该变量是如何定义的?如果那个守卫不起作用,这个序列将无限地递归。
如果你把DFVMH作为一个内联类,那么它的名字可能会以“java.lang [...]”开头(毕竟它在java.lang.Object中),因此不会通过所有的long if语句name.startsWith
。