1

想象一下两个简单的 java 应用程序。他们都实现了同一个 JAR 文件,其中包含一个像这样的枚举文件:

enum enum1{
   value1;
}

在这两个应用程序中,我都打印了 enum1.value1 的哈希码。

System.out.print(enum1.value1.hashCode());

即使两个应用程序实现的 JAR 文件相同,由于哈希码不相等,JVM 是如何工作的?

为什么哈希码不相等,因为它是两个应用程序实现的同一个 JAR 文件?

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

编辑 2
这是架构:

App1.jar              Commons.jar         App2.jar
App1Main.class        Commons.class       App2Main.class 

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

System.out.println(Commons.getInstance().hashCode());

两个 java 应用程序都像“java -jar app1”和“java -jar app2”一样运行,因此它们运行时有两个进程。

但是它们打印不同的哈希码,也就是我相信的(如果我错了,请纠正我),因为它们是由不同的类加载器加载的。但是当我在两个应用程序中打印类加载器时,神秘感就来了:

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

然后哈希码在两个应用程序中是相等的。

4

4 回答 4

2

目前尚不清楚您是否在谈论同一进程中的两个应用程序。即使你是,如果这两个应用程序有不同ClassLoader的实例加载同一个 jar 文件,就 JVM 而言,这两种枚举类型是不同的类型。如果您想要两个应用程序使用的进程中的单一类型,则必须由单个类加载器加载它。

于 2012-06-26T07:46:20.877 回答
1

请参阅Object.hashCode()的 Javadoc

hashCode 的一般合约是:

  1. 每当在 Java 应用程序执行期间对同一个对象多次调用它时,hashCode 方法必须始终返回相同的 integer ,前提是没有修改对象上的 equals 比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。

  2. 如果两个对象根据 equals(Object) 方法相等,则对两个对象中的每一个调用 hashCode 方法必须产生相同的整数结果。

  3. 如果根据 equals(java.lang.Object) 方法,如果两个对象不相等,则不需要对两个对象中的每一个调用 hashCode 方法都必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

这通常通过将对象的内部地址转换为整数来实现

所以你的结果对我来说似乎完全合法。如果您需要哈希码保持一致,也许您做错了,因为 API 不打算以这种方式使用。也许你可以说出你的目标。

于 2012-06-26T08:01:56.260 回答
0

enum 只是一个关键字,它使声明的类型类(例如 enum Day 意味着您将拥有一个像 Day 扩展 Enum 之类的类),类是对象的简单模板,它将在 JVM 中构造,具有自己的哈希码所以很明显,当您创建一个新对象时,您将获得新的哈希码,这就是您获得新哈希码的原因,请参阅以下链接以获取更多详细信息......

http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html

清楚地观察“所有枚举都隐式扩展 java.lang.Enum。由于 Java 不支持多重继承,因此枚举不能扩展其他任何东西”这一点很清楚。

于 2012-06-26T09:32:17.943 回答
0

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

于 2012-06-26T07:47:29.057 回答