2014-10-15 2 views
0

Почему Exception классы (например, RuntimeException) не реализуют equals() метод?Почему классы исключений в Java НЕ реализуют метод equals?

Например, output для этого кода false:

/* Name of the class has to be "Main" only if the class is public. */ 
class Ideone 
{ 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     final RuntimeException e1 = new RuntimeException("e"); 
     final RuntimeException e2 = new RuntimeException("e"); 
     System.out.println(e1.equals(e2)); 
    } 
} 

Есть ли причина, почему equals() не реализована? Мне кажется, это было бы очень полезно.

Редактировать: Позвольте мне рассказать о проблеме, так как кажется, что большинство людей считают, что реализация equals() не будет полезна.

Хотелось бы знать, почему Исключения должны обрабатываться иначе, чем обычные объекты, и их следует сопоставлять только в том случае, если это один и тот же экземпляр. Не хватает ли информации о себе для сравнения с другими объектами. Например, базовый StackTraceElement, который, как я предполагаю, хранит стек вызовов, уже реализует метод equals.

Есть ли что-то в определении Исключений, которые мешают им реализовать метод equals на основе их атрибутов?

+8

Зачем вам нужно сравнивать 'Exception'? Мне никогда не приходилось сравнивать «Исключение». – rgettman

+2

Если вы хотите сравнить объекты RuntimeException, создайте свой собственный подкласс, который переопределяет 'equals'. – deyur

+11

Эти исключения будут иметь разные трассировки стека, так что вы действительно считаете их равными? –

ответ

2

Well Exception s обычные экземпляры экземпляров. Исключения могут поддерживать состояние.

Например, можно утверждать, что исключение, созданное в одной конкретной строке с определенным сообщением, не равно исключению, создаваемому на следующей строке.

Даже если ошибка возникает на той же линии, с тем же стек вызовов, но разные пробеги программ, можно сказать, что исключения не то же самое ... Так первая программа может быть вызвана с:

java -jar program.jar "arg1" & java -jar program.jar "arg2" 

программ имеют разные pid, брошены на другой штамп времени, ...

однако можно реализовать метод equals самостоятельно, используя наследование (для собственных определен Exception ы):

public class WeirdException extends Exception { 

    @Override 
    public boolean equals (Object obj) { 
     return (obj instanceof WeirdException); 
    } 

} 

В конце концов, StackTrace только "хранится" в Exception во время строительства, совершенно правильная программа Java заключается в следующем:

public class MyClass { 


    public static void main(String args[]){ 
     Exception ex = new IndexOutOfBoundsException(); 
     ex.printStackTrace(System.out); 
    } 
} 

Результат:

java.lang.IndexOutOfBoundsException 
    at MyClass.main(MyClass.java:15) 

В другими словами, throw не имеет отношения к Exception. throw просто означает «альтернативный return». Это не имеет ничего общего с хранением трассировки стека, ...

+0

Это не тест равенства, а просто экземпляр теста. –

+0

@ChrisStratton: В случае, если Exception не содержит состояния, это более или менее одинаково.Но первый вопрос, который нужно задать (это задокументировано в ответе), это когда два «Исключения» равны. Нужно ли им использовать одну и ту же стек? Тот же процесс? Та же самая отметка времени ... –

+0

Я вижу, к чему вы клоните. Но на первой строке вы имели в виду, что Исключения - это не обычные экземпляры класса? – SANDeveloper

2

Обратите внимание, что, хотя Exception не отменяет equals, у него есть реализация, то одна унаследованная от Object, который сравнивает идентичность.

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

Исключения не очень подвержены значению семантики. Что бы вы сделали, если бы имели, использовали их как ключи хеш-таблицы? В этом случае вы можете реализовать класс оболочки, который equals и hashCode ведут себя так.

2

Существует простое объяснение: два разных экземпляра Exception ни в коем случае не равны.

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

Два разных экземпляра Exception s никогда не должны быть равными, просто потому, что они не могут стоять за одно и то же.

Смежные вопросы