Как напечатать адрес объекта, если вы переопределили метод toString
Я новичок в Java. Теперь я изучаю equals и == и переопределение equals и toString.
Я хотел бы использовать как метод toString, который я переопределил, так и метод по умолчанию, который унаследован от класса Object.
Мне не удалось использовать этот супермодификатор для достижения этого метода.
Это только для образовательных целей. То, что я хотел бы получить, более понятно, если вы посмотрите на комментарии в моем коде.
Не могли бы вы мне помочь?
Мой код:
public class EqualTest{
public static void main(String[] args){
Employee alice1 = new Employee("Alice Adams", 75000, 1987, 12, 15);
//System.out.super.println(alice1);
Employee alice2 = alice1;
//System.out.super.println(alice2);
Employee alice3 = new Employee("Alice Adams", 75000, 1987, 12, 15);
//System.out.super.println(alice3);
System.out.println("alice1==alice2: " + (alice1==alice2));
System.out.println("alice1 == alice3: " + (alice1==alice3));
System.out.println("alice1.equals(alice3): " + alice1.equals(alice3));
}
}
class Employee{
...
public String toString(){
return getClass().getName() + "[name = " + name +
", salary=" + salary + ", hireDay=" + hireDay + "]";
}
}
Ответы
Ответ 1
Строго говоря, вы не можете напечатать адрес объекта в чистой Java. Число, которое выглядит как адрес объекта в String, созданный Object.toString()
, является объектом "hashcode identity". Он может или не может быть связан с текущим адресом объекта:
-
В спецификациях не указывается, как рассчитывается идентификационный номер хэш-кода. Он намеренно оставлен неуказанным.
-
Так как число является хэш-кодом, оно не может измениться. Таким образом, хотя это (обычно) связано с адресом объекта, это будет адрес объекта во время первого обращения к хэш-коду. Это может отличаться от текущего адреса, и будет отличаться, если GC переместил объект с первого раза, когда был отмечен hashcode идентификатора объекта.
-
На 64-битной JVM (с достаточно большим размером кучи/без использования сжатых oops) адреса не будут вписываться в идентификационный номер хэш-кода, который возвращается как int
.
Во всяком случае, способ получить этот номер - вызвать System.identityHashCode(obj)
.
Если вам действительно нужен текущий адрес объекта, вы можете получить его, используя JNI и собственный метод (и некоторое нарушение абстракции), или используя методы в классе Unsafe
. Но будьте осторожны, что оба этих подхода не переносятся... и что адреса объектов, которые они дают вам, могут "ломаться", когда GC работает.
Ответ 2
Если вы хотите выполнить сортировку по умолчанию toString()
, вы можете использовать метод System.identityHashCode()
. По умолчанию toString()
будет выглядеть следующим образом:
public String toString(Object o) {
return o.getClass().getName() + "@" +
Integer.toHexString(System.identityHashCode(o));
}
Ответ 3
Вы можете вызвать метод super() для выполнения соответствующего метода суперкласса.
class Employee{
...
public String toString(){
String s = super.toString();
return getClass().getName() + "[name = " + name +
", salary=" + salary + ", hireDay=" + hireDay + "]" + s;
}
toString() в классе Object выглядит следующим образом
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
Ответ 4
Вот подробный ответ об переопределении равных и hashcode
Какие проблемы следует учитывать при переопределении equals и hashCode в Java?
Ключевым моментом является
Связь между этими двумя методами:
Всякий раз, когда a.equals(b), тогда a.hashCode() должен быть таким же, как b.hashCode().
Ответ 5
Вы можете создать другой метод внутри вашего класса Employee, чтобы использовать метод super toString.
См. пример:
public class Employee {
public String toString() {
return "MyToStringMethod";
}
public String superToString() {
return super.toString();
}
public static void main(String[] args) {
Employee b = new Employee();
System.out.println(b);
System.out.println(b.superToString());
}
}
или объединить оба метода:
public class Employee {
public String toString() {
return super.toString() + " MyToStringMethod";
}
public static void main(String[] args) {
Employee b = new Employee();
System.out.println(b);
}
}