Как вы получаете "ссылку на объект" объекта в java, когда toString() и hashCode() были переопределены?

Я хотел бы напечатать "ссылку на объект" объекта в Java для целей отладки. То есть чтобы объект был одинаковым (или другим) в зависимости от ситуации.

Проблема заключается в том, что рассматриваемый класс наследуется от другого класса, который переопределяет как toString(), так и hashCode(), которые обычно дают мне идентификатор.

Пример ситуации: Запуск многопоточного приложения, где я (во время разработки) хочу проверить, используют ли все потоки один и тот же экземпляр объекта ресурса или нет.

Ответ 1

Что именно вы планируете делать с ним (что вы хотите сделать, имеет значение с тем, что вам нужно будет вызвать).

hashCode, как определено в JavaDocs, говорится:

Насколько разумно практично, метод hashCode, определенный классом Object, возвращает разные целые числа для разных объектов. (Обычно это реализуется путем преобразования внутреннего адреса объекта в целое число, но эта технология реализации не требуется языком программирования Java & trade;)

Итак, если вы используете hashCode(), чтобы узнать, является ли это уникальным объектом в памяти, что не является хорошим способом его выполнения.

System.identityHashCode делает следующее:

Возвращает тот же хэш-код для данного объекта, который будет возвращен методом hashCode() по умолчанию, независимо от того, переопределяет ли данный класс объекта hashCode(). Хэш-код для нулевой ссылки равен нулю.

Что, за то, что вы делаете, похоже на то, что вы хотите... но то, что вы хотите сделать, может быть небезопасным в зависимости от того, как реализована библиотека.

Ответ 2

Вот как я это решил:

Integer.toHexString(System.identityHashCode(object));

Ответ 3

Double equals == всегда будет проверяться на основе идентификатора объекта, независимо от реализации хеш-кода объектов или равно. Конечно, убедитесь, что ссылки на объекты, которые вы сравниваете, - это volatile (в версии 1.5+ JVM).

Если вы действительно должны иметь исходный результат Object toString (хотя это не лучшее решение для вашего примера использования), библиотека Commons Lang имеет метод ObjectUtils.identityToString(Object), который будет делать то, что вы хотите. Из JavaDoc:

public static java.lang.String identityToString(java.lang.Object object)

Получает toString, который будет созданный Объектом, если класс не переопределить toString. null будет return null.

 ObjectUtils.identityToString(null)         = null
 ObjectUtils.identityToString("")           = "[email protected]"
 ObjectUtils.identityToString(Boolean.TRUE) = "[email protected]"

Ответ 4

Вы не можете безопасно делать то, что хотите, поскольку hashCode() по умолчанию не может возвращать адрес, и было упомянуто, что возможны несколько объектов с одним и тем же хэш-кодом. Единственный способ выполнить то, что вы хотите, - это фактически переопределить метод hashCode() для рассматриваемых объектов и гарантировать, что все они предоставляют уникальные значения. Возможно ли это в вашей ситуации - это еще один вопрос.

Для записи я испытал несколько объектов с одним и тем же хэш-кодом по умолчанию в VM VM, работающем на сервере WAS. Из-за этого у нас был дефект, когда объекты, помещенные в удаленный кеш, были бы перезаписаны. Это было для меня открытием для глаз в тот момент, поскольку я предположил, что хэш-код по умолчанию был адресом памяти объектов.

Ответ 5

Добавьте уникальный идентификатор ко всем вашим экземплярам, ​​т.е.

public interface Idable {
  int id();
}

public class IdGenerator {
  private static int id = 0;
  public static synchronized int generate() { return id++; }
}

public abstract class AbstractSomething implements Idable {
  private int id;
  public AbstractSomething () {
    this.id = IdGenerator.generate();
  }
  public int id() { return id; }
}

Извлечь из AbstractSomething и запросить это свойство. Будет безопасно внутри одного vm (если не играть в игру с загрузчиками классов, чтобы обойти статику).

Ответ 6

мы можем просто скопировать код из строки tostring класса объекта, чтобы получить ссылка строки

class Test
{
  public static void main(String args[])
  {
    String a="nikhil";     // it stores in String constant pool
    String s=new String("nikhil");    //with new stores in heap
    System.out.println(Integer.toHexString(System.identityHashCode(a)));
    System.out.println(Integer.toHexString(System.identityHashCode(s)));
  }
}