Java JVM是否为在不同应用程序中实现的类创建了两个单独的实例?

Java JVM是否为在不同应用程序中实现的类创建了两个单独的实例?,java,jar,jvm,Java,Jar,Jvm,想象两个简单的java应用程序。 它们都实现了相同的JAR文件,其中包含如下所示的枚举文件: enum enum1{ value1; } 在这两个应用程序中,我都打印enum1.value1的hashcode System.out.print(enum1.value1.hashCode()); 即使两个应用程序实现的JAR文件相同,哈希代码也不相等,JVM如何工作 既然这两个应用程序实现的是同一个JAR文件,为什么哈希代码不相等 编辑 我有两个访问数据库的应用程序。它们在同一个JVM中

想象两个简单的java应用程序。 它们都实现了相同的JAR文件,其中包含如下所示的枚举文件:

enum enum1{
   value1;
}
在这两个应用程序中,我都打印enum1.value1的hashcode

System.out.print(enum1.value1.hashCode());
即使两个应用程序实现的JAR文件相同,哈希代码也不相等,JVM如何工作

既然这两个应用程序实现的是同一个JAR文件,为什么哈希代码不相等

编辑
我有两个访问数据库的应用程序。它们在同一个JVM中运行。我想实现一种锁定机制,这样当应用程序1写入数据库时,应用程序2必须等待轮到它(即当应用程序1释放锁时)。如果可能的话,我的解决方案是创建一个声明了一些可重入锁的接口,或者创建一个应充当锁并由两个应用程序使用的枚举。但是,接口/枚举的实例在两个应用程序中应该相等,因为您只能同步同一个对象

编辑2
这就是架构:

App1.jar              Commons.jar         App2.jar
App1Main.class        Commons.class       App2Main.class 
App1和App2都包括Commons.jar。commons.class只是一个简单的单例类。 在App1和App2中,我都打印commons实例哈希代码:

System.out.println(Commons.getInstance().hashCode());
这两个java应用程序都像“java-jar app1”和“java-jar app2”一样运行,因此在运行时有两个进程

但它们打印不同的哈希代码,这就是我所相信的(如果我错了,请纠正我),因为它们是由不同的类装入器装入的。但当我在两个应用程序中打印类加载器时,神秘主义者出现了:

System.out.print(ClassLoader.getSystemClassLoader().hashCode());

那么这两个应用程序中的哈希代码是相等的

不清楚您是否在谈论同一流程中的两个应用程序。即使是这样,如果这两个应用程序有单独的
ClassLoader
实例加载相同的jar文件,那么就JVM而言,这两种枚举类型是不同的类型。如果您希望在两个应用程序使用的进程中使用一个类型,那么它必须由一个类加载器加载。

将JAR视为静态资源,其中包含可能运行的应用程序的配方。当应用程序实际运行时,所有资源都会使用特定于操作系统的规则加载到计算机内存中。这些规则不强制在同一虚拟内存地址中加载类。

有关详细信息,请参阅Javadoc

hashCode的总合同为:

  • 在一次调用过程中,在同一对象上多次调用 在执行Java应用程序时,hashCode方法必须一致 如果没有在equals中使用信息,则返回相同的整数 修改对象上的比较此整数不需要保留 从应用程序的一次执行到另一次执行的一致性 属于同一应用程序。

  • 如果两个对象根据 equals(Object)方法,然后在每个 两个对象必须产生相同的整数结果

  • 如果两个对象根据 equals(java.lang.Object)方法,然后在 这两个对象中的每一个都必须产生不同的整数结果。 但是,程序员应该知道,生成不同的 不相等对象的整数结果可能会提高 哈希表

  • 这通常是通过转换 将对象转换为整数


    所以你的结果在我看来是完全合理的。如果您需要哈希代码保持一致,可能您做得不对,因为API不打算以这种方式使用。也许您可以告诉我们您的目标。

    enum只是一个关键字,它构成了声明的类型类(例如,enum Day意味着您将拥有一个类似Day extensed enum的类),类是对象的一个简单模板,它将在J.V.M中构造,J.V.M具有自己的哈希代码,因此很明显,当您创建一个新对象时,您将获得新的哈希代码,这就是您获得新哈希代码的原因 请参阅以下链接以了解更多详细信息


    请注意“所有枚举都隐式扩展java.lang.Enum。由于java不支持多重继承,因此枚举不能扩展任何其他内容”这一点。如何使应用程序由同一个类加载器加载?有趣的是,一如既往:)您所说的“两种枚举类型是不同的类型”是什么意思?@Raffaele:
    对象是独立的,您无法将一个类的实例强制转换为另一个类。好像它们是完全分开的。@Rox:这取决于上下文,你没有告诉我们任何事情。我们甚至不知道它们是否在同一个JVM中运行@真奇怪。我认为
    classLoadedByA.equals(classLoadedByB)
    应该是真的,
    classLoadedByA.cast(foreignistance)
    也应该运行良好,否则怎么处理这个问题呢?(但也许这值得再问一个问题,在评论中是不合适的)你需要他们平等吗?是的,看看我的编辑来解释。我相信你想要的解决方案是脆弱的。考虑使用一个公共数据库连接池,而两个应用程序只有一个条目。在应用程序1完成之前,应用程序2无法访问数据库。