我通过SOOT-ECLIPSE插件设置一个类作为主类,并希望它像单例一样操作。但是我的实现似乎不工作,因为我每次运行都会得到不同的实例。
我尝试使用包装器并从那里调用单例类,以避免出现以下情况这个类是由煤烟类加载器收集的垃圾。但是我也得到了不同的实例
我确认它在一个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();
}
(From comments…)
我的观点是,我想运行这个类,每次都得到相同的实例。
听起来你对什么是单身有误解。如果你的应用运行了两次,即
$ java MyApp
[output]
$ java MyApp
[output]
则它们是完全独立的JVM调用。当第一次运行完成后,不再是实例——JVM分配的所有内存都将被释放。
如果你需要一个持久的对象(即,即使Java没有运行,它仍然存在于某个地方),那么这是一个非常不同的场景,你应该考虑序列化——尽管你仍然不应该期望两个运行在不同JVM实例上的应用程序在内存中看到相同的对象。
编辑:现在我们知道您在Soot下运行,这可能会每次都创建一个单独的类加载器,因此您将以方式获得不同的实例。从根本上说,您需要了解代码运行的上下文,并在问题中提供该信息(以及您正在观察的内容)。
似乎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
}
}
显然,如果文件以某种方式被删除,那么这将再次被视为"第一次运行"。
所以可以对任何可用的持久数据存储做类似的事情。