Всегда ли ((Object) (this)). ToString () вызывать базовую реализацию? - PullRequest
0 голосов
/ 03 сентября 2018

У меня есть реализация toString(), которая опирается на некоторый код, который может вызвать исключение.

В этом случае я хочу переключиться на метод toString() по умолчанию.

С этой целью безопасно ли использовать

catch (Exception e){
    return ((Object)(this)).toString();
}

как обработчик для этого исключения? Другими словами, заставит ли это использовать метод Object toString().

Кажется, это работает в моем случае, но я волнуюсь, что это не стандартно и может вызвать рекурсию.

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Совсем нет. JVM определяет во время выполнения , основываясь на точном типе объекта, какой метод вызывать.

Ваш милый маленький кастинг ничего не добивается. Потому что вы не можете изменить тип ссылки во время выполнения при помощи приведения!

Одним из решений было бы иметь что-то вроде:

public String superToString() {
  return super.toString();
} 

внутри таких классов и вызывать этот метод явно. В качестве альтернативы, строка, которая в данный момент выполняет это приведение, может быть, конечно, заменена на return super.toString().

Но тогда, особенно вариант 1 только добавил бы «хуже к плохому». Как в: контракт toString() должен возвращать строку.

Просто никогда написать toString() методов, которые

  • требует много интенсивной работы или
  • может выдать исключение!

См. Как использовать метод toString в Java для дальнейших размышлений.

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

0 голосов
/ 03 сентября 2018

Нет. Если это произойдет, это победит полиморфизм во время выполнения, который является одной из фундаментальных особенностей Java (для методов). Выбранный метод зависит от того, к какому объекту вы его вызываете, а не от того, какой тип ссылки у вас есть на объект (это то, что изменяет приведение).

Вы можете использовать super.toString(), который будет использовать версию вашего суперкласса (которая может быть или не быть версией Object, но кажется достаточной для перечисленного вами варианта использования).

У меня есть реализация toString(), которая опирается на некоторый код, который может вызвать исключение.

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

Вызов версии super, вероятно, не идеален. Вместо этого, возможно, сгенерируйте строку, включающую смысл исключения.

...