`new Object()'似乎没有创建新对象,为什么?

时间:2013-11-21 11:34:02

标签: java object

我有一个奇怪的时刻。

ArrayList<Object> a = new ArrayList<Object>();
a.add(new Socket());
a.add(new Thread());
a.add("three");
a.add(a);
a.add(new Object());

for(Object output : a) {
    System.out.println(output);
}

输出:

Socket[unconnected]
Thread[Thread-0,5,main]
three
[Socket[unconnected], Thread[Thread-0,5,main], three, (this Collection)]
java.lang.Object@615e7597

每次运行时,新对象总是提供相同的十六进制字符串(Java doc Integer.toHexString(hashCode())),为什么会这样?为什么每次都不会产生不同的字符串?或者它是否重复使用同一个对象,因为它可以?

编辑:我多次尝试执行Java应用程序。

5 个答案:

答案 0 :(得分:5)

对象的哈希码通常是从其内部地址(ref http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode%28%29)计算的,所以如果你重新运行具有相同状态的程序,则内存中对象的地址可能是相同的每一次。

技术上并没有重用同一个对象,因为你正在退出JVM;它只是每次都遵循相同的步骤,在内存中的相同位置创建一个相同的对象,这会产生相同的哈希码,以便toString()返回。

答案 1 :(得分:1)

新对象恰好在与之前相同的内存位置创建,几乎没有执行。预计会发生变化。您可能会尝试执行该程序10次,我觉得至少2-3次将在不同的位置创建对象。

此JVM行为不能声称为错误。甚至在java中查看内存位置也是错误的,JVM可以选择在执行过程中将对象移动到不同的内存位置。

答案 2 :(得分:-1)

来自Object.hashCode文档:

hashCode的一般合约是:

  • 每当在同一个对象上多次调用它时 执行     对于Java应用程序,hashCode方法必须始终返回相同的整数,前提是equals中不使用任何信息 对象的比较被修改。不需要保留该整数 从一个应用程序的执行到另一个执行的一致性 相同的申请。
  • 如果两个对象根据equals(Object)方法相等,则必须对两个对象中的每一个调用hashCode方法 产生相同的整数结果。
  • 如果两个对象根据equals(java.lang.Object)方法不相等,则不需要调用hashCode方法 在两个对象中的每一个上必须产生不同的整数结果。但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能。

因此,您的Object始终具有相同的hashCode是有效的。

答案 3 :(得分:-1)

如果System.out.println找到对象引用,则始终打印toString()方法。这里List存储不同的对象引用,具有不同的toString实现。

 ArrayList<Object> a = new ArrayList<Object>();
    a.add(new Socket());

例如,SockettoString被覆盖为

public String toString() {
    try {
        if (isConnected())
            return "Socket[addr=" + getImpl().getInetAddress() +
                ",port=" + getImpl().getPort() +
                ",localport=" + getImpl().getLocalPort() + "]";
    } catch (SocketException e) {
    }
    return "Socket[unconnected]";
  }

因此,您会看到new Socket()的输出为Socket[unconnected]

答案 4 :(得分:-1)

是的,就像你说的那样。我试图多次执行Java应用程序。结果和你说的一样。但是,结果就在我们执行Java应用程序时。但是,当我们在eclipse中重新编译 Java应用程序时,结果并不相同。像这样,你将得到不同的哈希码值。首先,JVM会在第一次执行 java程序时将字节文件加载到内存中。每次执行都会得到相同的哈希码值,就像“Rich Smith”的回复一样。编译程序时,每次都会将bytes文件加载到内存中。所以我们将得到不同的hashcode值并得到不同的Object。