2014-12-12 5 views
2

Пожалуйста, обратите внимание: Я не спрашиваю, как заставить все классы переопределить toString() в их исходном коде. Пожалуйста, внимательно прочитайте вопрос.Как заставить вызов суперкласса Object.toString реализации(), а не подкласс перекрывая реализации на объекте в Java

Все классы в java расширяют класс Object. Если какой-либо класс имеет переопределение toString(), вызов Object.toString() фактически выполнит метод переопределения.

Например:

String test = "StackOverflow"; 
Object testobj1 = (Object) test; 
System.out.println(testobj1.toString()); // prints "StackOverflow" 
Object testobj2 = new Object(); 
System.out.println(testobj2.toString()); // prints "[email protected]<Object.hashcode() in hex>" 

Что мне нужно для вызова testobj1 «s toString() фактически выполнить toString() метода, Object класса. Что-то вроде:

System.out.println([[testobj1 as Object]] .toString()); // prints "[email protected]<Object.hashcode() in hex>" 

Я попытался с помощью:

System.out.println(testobj1.getClass().getName() + '@' + Integer.toHexString(testobj1.hashCode())); 

Но это также имеет те же проблемы, что и выше. Метод hashCode() также переоценивается классом String, поэтому он выполняет StringhashCode(), а не ObjecthashCode().

Можно ли вызвать переопределенный метод, а не метод переопределения?

Обратите внимание: Использование String класса является лишь примером. Не основывайте свой ответ на предположении, что объект всегда является объектом String.

Также предположит: У меня нет доступа к исходному коду классов, поэтому я не могу просто удалить toString() реализации из них или делать вещи, как создать абстрактный класс. Это должно работать для любого объекта (в том числе и собственных классов Java или любого API, например String, HashMap, HttpServlet и т. Д.). Это также означает, что я не ищет ответы like these.

ответ

4

Чтобы получить фактический (исходный) хеш-код, вам необходимо использовать System.identityHashCode().

Попробуйте этот код:

public static void main(String[] args) { 
    String test = "StackOverflow"; 
    Object testobj1 = (Object) test; 
    System.out.println(testobj1.toString()); // prints "StackOverflow" 
    System.out.println(testobj1.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(testobj1))); 
    System.out.println(test.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(test))); 
    Object testobj2 = new Object(); 
    System.out.println(testobj2.toString()); 
    System.out.println(testobj2.getClass().getName() + '@' + Integer.toHexString(System.identityHashCode(testobj2))); 
} 

Выход:

StackOverflow 
[email protected] 
[email protected] 
[email protected] 
[email protected] 
+0

достаточно близко! Полностью забыл об этом методе. Это не общее решение, но оно работает для восстановления исходной функциональности 'Object.toString()'! – ADTC

+2

@ADTC - Да, это так .. переопределенные методы динамически отправляются, поэтому я не вижу другого пути здесь. – TheLostMind

+1

Да, но это сработает для меня, поскольку я только хочу реплицировать 'toString()'. Но мне интересно, возможно ли общее решение, используя ** отражение **? * Возможно, слишком много, но возможно ли это? * – ADTC

2

Вы не можете сделать это.

Потому что java всегда использует метод переопределения.

Его вызов не отменяется. Это не имеет смысла. Вы переопределяете метод, потому что вам не нужно использовать родительский метод.

+0

Хотя отредактированный ответ непосредственно отвечает на мой вопрос, ответ TheLostMind в решает мою актуальную проблему. Я буду склонен принять это вместо этого. Спасибо за понимание. – ADTC

+1

Я действительно прекратил спрашивать людей * почему вы пытаетесь это сделать? * ..: P – TheLostMind

+0

что вы остановили, чтобы задать вопрос –