Frankie
15
java
time
除了重新编译之外,rt.jar有什么方法可以用currentTimeMillis()我自己的一个替换呼叫吗?
1#正确的方法是使用Clock对象和抽象时间.
我知道但我们将运行由无数开发人员开发的代码,这些开发人员尚未实现Clock或已经实现了自己的实现.
2#使用像JMockit这样的模拟工具来模拟该类.
即使这只适用于禁用Hotspot -Xint并且我们使用下面的代码成功,但它不会"持久"在外部库上.这意味着你必须在任何地方模拟它,因为代码不受我们的控制,是不可行的.所有代码main()都返回0 milis(从示例中),但a new DateTime()将返回实际系统millis.
@MockClass(realClass = System.class)
public class SystemMock extends MockUp {
// returns 1970-01-01
@Mock public static long currentTimeMillis() { return 0; }
}
3#System使用-Xbootclasspath/p(编辑) 重新声明启动
尽管可能,虽然您可以创建/更改方法,但有问题的方法被声明为public static native long currentTimeMillis();.如果不深入研究Sun的专有和原生代码,你就无法改变它的声明,这将使这成为逆向工程和不稳定的方法.所有最近的SUN JVM都崩溃,出现以下错误:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x00000, pid=4668, tid=5736
4#使用自定义ClassLoader(评论中建议的新测试)
虽然使用-Djava.system.class.loaderJVM 替换系统CL的微不足道实际上加载了使用默认classLoader的自定义classLoader,并且甚至没有通过自定义CL推送System.
public class SimpleClassLoader extends ClassLoader {
public SimpleClassLoader(ClassLoader classLoader) {
super(classLoader);
}
@Override
public Class> loadClass(String name) throws ClassNotFoundException {
return super.loadClass(name);
}
}
我们可以看到java.lang.System从rt.jar使用中加载java -verbose:class
Line 15: [Loaded java.lang.System from C:\jdk1.7.0_25\jre\lib\rt.jar]
我的选择已经用完了.
有什么方法我不见了?