Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > адрес объекта


Автор: zomber 8.1.2012, 11:56
подскажите, как напечатать адрес объекта
нужно для отладки
если написать System.out.println(myObj);
адрес напечатается.... но тока если нет метода toString

а как быть если есть toString ?

Автор: Dummy 8.1.2012, 13:03
То, что вы называете адресом, - это на самом деле хэш-код. Чтобы его получить, можно сделать так:
Код

int hash = myObj.hashCode();
System.out.println(hash);

Но в этом случае, если в классе вашего объекта метод hashCode() переопределен, вы будете получать уже числа, посчитанные по какому-то недефолтному алгоритму. Например, если переопределено так:
Код

@Override
public int hashCode() {
    return 45;
}

то всегда будет возвращаться одно и то же число.

Чтобы для отладки получить значение хэш-кода по дефолтному алгоритму, можно сделать так:
Код

int hash = System.identityHashCode(myObj);
System.out.println(hash);

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

Автор: zomber 8.1.2012, 13:08
Цитата(Dummy @ 8.1.2012,  13:03)
Более того, хэш даже не обязан быть разным для разных объектов.

вот это-то и смущает

ладно, всё равно спасибо

Автор: AlexeyVorotnikov 11.1.2012, 10:32
В Java просто-напросто нет такого понятия как "адрес объекта". Так что увы и ах...

Автор: Absinthe 11.1.2012, 13:44
zomber, а для какой такой отладки это нужно?

Автор: jk1 11.1.2012, 15:07
zomber, 

В силу особенностей сборки мусора в Java реальный адрес объекта меняется несколько раз за время его жизни. При помощи sun.misc.Unfase (доступен только в JVM от Oracle) Вы сможете получить реальный адрес, но смысла в этом не будет - в следующий момент объект может быть перемещен.

Автор: zomber 13.1.2012, 13:42
Цитата(AlexeyVorotnikov @  11.1.2012,  10:32 Найти цитируемый пост)
В Java просто-напросто нет такого понятия как "адрес объекта". Так что увы и ах... 


просто хотелось как-то уникально идентифицировать объект
и если для своих объектов можно использовать свой идентификатор
то как быть со стандартными типами, например, Integer\String\ArrayList\HashMap....

а хеш всегда оставляет вероятность неуникальности, имхо

Автор: priam220 13.1.2012, 18:40
Integer\String должны идентифицироваться по значению, имхо. В частности, в java встроены механизмы, кот именно так и делают. Это исходит из логики самих объектов - "целое число", "строка". 
Идентичность коллекций обпределяется идентичностью их составляющих. Сами по себе они не несут никакой смысловой нагрузки.

Автор: dorogoyIV 14.1.2012, 10:38
Цитата(zomber @  13.1.2012,  13:42 Найти цитируемый пост)
просто хотелось как-то уникально идентифицировать объект

бери миллисекунды, да и все...  smile 

Автор: jk1 14.1.2012, 12:56
Цитата

бери миллисекунды, да и все... 


System.currentTimeMilis() не дает милисекундной точности на многих платформах. Просто потому, что та же WinXP точности больше ~10ms дать не может.
Если делать последовательную аллокацию, то время в объектах будет записано одинаковое.

На моей машине вот этот пример показывает одинаковое время для всех:
Код

public class Test  {

    private long time;

    public Test() {
       time = System.currentTimeMillis();
    }

    @Override
    public String toString() {
        return String.valueOf(time);
    }

    public static void main(String[] args) {
        for (int i=0; i< 10; i++){
            System.out.println(new Test());
        }
    }
}

Автор: dorogoyIV 14.1.2012, 12:59
jk1, я предполагал такой ответ. но можно ведь сделать задержку...
Код

 Sleep(100);

Автор: jk1 14.1.2012, 13:06
Цитата

jk1, я предполагал такой ответ. но можно ведь сделать задержку...


 smile Не хватает только аннотации @Magic.

 Аллокаций может происходить очень и очень много, часто без профайлера даже не подозреваешь сколько. А тут задержка при создании объекта в 0.1 секунду...
Я подобную штуку как-то делал в unit-тестах, эмпирически подобрал 25ms как минимальный различимый интервал на всех машинах, где только выполнялись эти тесты. Но для продакшна такое решение не подходит совершенно. 

Правильно топикстартеру выше по теме советуют - равенство объектов определяют по данным.

Автор: dorogoyIV 14.1.2012, 13:35
может и правильно, я же не спорю...
только вот сколько уйдет времени на генерацию идентификатора - ?
конечно же Sleep(100) - это много. это же я так, для примера привел...

если считать время, то:
Код

public class Main
{
 public static void main(String [] args)
 {
  long start_time = System.currentTimeMillis();

  long ID = start_time; // НЕ заморачиваемся с генерацией ID
  System.out.println(System.currentTimeMillis() - start_time);

  long time_ID = createID(); // заморачиваемся с генерацией ID
  System.out.println(time_ID - start_time);
 }

 private static long createID()
 {
  for(int i = 0; i < 10000000; i++)
  {
   // эмулируем какую то работу генерации ID ...
   // это еще без вычислений каких либо...!
  }
  long l = System.currentTimeMillis();
  return l;
 }
}


я вообще то согласен с priam220 
Цитата(priam220 @  13.1.2012,  18:40 Найти цитируемый пост)
Идентичность коллекций обпределяется идентичностью их составляющих. Сами по себе они не несут никакой смысловой нагрузки.


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)