我通过SOOT-ECLIPSE插件设置一个类作为主类,并希望它像单例一样运行。但是我的实现似乎不起作用,因为每次运行都会得到不同的实例。
我尝试使用包装器并从那里调用单例类,以避免出现这种情况 这个类是由soot的类加载器收集的垃圾。但我也得到了不同的实例。
我确认它在一个JVM上运行,因为我在每次运行时获得的PID相同 到每次运行时更改的类的实例。
我真的很感激对这一点的任何见解。
public class MyMain{
private static boolean isFirstInstance = true;
private static class MyMainHolder {
private static final MyMain INSTANCE = new MyMain();
}
public static synchronized MyMain getInstance() {
return MyMainHolder.INSTANCE;
}
private MyMain() {
if (MyMainHolder.INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}
}
public static void main(String[] args) {
System.out.println("PID: " + ManagementFactory.getRuntimeMXBean().getName());
MyMain tmp = getInstance();
}
答案 0 :(得分:5)
(来自评论......)
我的观点是我想运行这个类并且每次都获得相同的实例。
听起来你对单身人士有什么误解。如果你两次运行你的应用程序,即
$ java MyApp
[output]
$ java MyApp
[output]
然后这些是完全独立的JVM调用。第一次运行完成后, 不再有实例 - JVM分配的所有内存都将被释放。
如果你需要一个持久性对象(即即使Java没有运行仍然存在的对象),那么这是一个非常不同的场景,你应该看一下序列化 - 虽然你仍然不应该期望在JVM的不同实例上运行的两个应用程序在内存中看到相同的对象。
编辑:既然我们知道您在Soot下运行,那么每次都可以创建一个单独的类加载器,这样您就可以获得不同的实例那个的方式。从根本上说,您需要了解代码运行的上下文,并在问题中提供该信息(以及您正在观察的内容)。答案 1 :(得分:1)
看来,OP实际上希望能够在程序的第一次运行和后续运行之间进行区分。这样就可以了:
public static void main(String[] args) {
File file = new File("has_been_run");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
// first time
} else {
// subsequent times
}
}
显然,文件是以某种方式删除的,然后算作"第一次运行"试。
因此可以使用您可用的任何持久数据存储执行类似操作。