2010-09-30 2 views
6

Прямой ответ заключается в том, что интерфейс Comparator.compare s указан как таковой, что он не генерирует исключения. Но почему?Java: почему я не могу исключить исключение в Comparator?

Или, говоря иначе: Мой Comparator должен зависеть от функции, которая может генерировать исключение. Теоретически этого не должно быть. Но если это произойдет, я хочу, чтобы он вырывался из всей функции, где я использую это ComparatorCollections.sort). То есть Я хочу, чтобы он просто вел себя так, как если бы произошло необработанное исключение.

Похоже, что это невозможно естественным образом (потому что если интерфейс говорит, что он не может генерировать исключение, он не может).

Как бы это решить? С уродливым try/catch и распечатать исключение и надеяться, что я его узнаю? Это кажется довольно уродливым.

+2

Вы считали, что вместо этого вы выбрали исключение RuntimeException? (возможно, обертывание проверенного исключения) –

ответ

5

В этом случае я бы сбросил AssertionError, так как вы предполагаете, что исключение не может быть поднято. Не забудьте использовать метод initCause() для распространения информации (AssertionError не имеет конструктора, принимающее Throwable)

+2

'AssertionError' имеет конструктор, принимающий' Object', который будет использоваться в качестве причины, если это 'Throwable'. (Случайная заметка: я считаю, что они улучшают это в JDK7.) – ColinD

+0

@ColinD Вау ... Я только что кое-что узнал. Благодарю. – gawi

13

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

3

Это договор метода Comparator.compare. Если вы хотите использовать его, вы должны просто следовать правилу, чтобы не выбрасывать проверенные исключения из него :) Между тем вы можете исключить исключенное исключение (RuntimeException или его подкласс), и это не нарушит контракт.

0

Есть 2 способа решения этой:

  1. Ловля исключение и метательные его внутри java.lang.RuntimeException() или
  2. Ловля исключение и лесозаготовки его с помощью Log4J или SLF4J (или любого регистратора завода вы чувствовали себя комфортно с).

Контракт на метод сравнения компаратора не вызывает исключений.

+2

Я бы посоветовал не регистрировать ошибку и продолжить. Это не ошибка, которую вы должны игнорировать. – gawi

+0

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

+0

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

1

Вы задавать разные вопросы в названии вопроса и в теле вопроса.

Вы не поняли, почему функция исключения, используемая методом compare(), выдает исключение. Это либо потому, что в коллекции есть определенные несравнимые объекты (например, нумерологическое значение NaN), либо это потому, что есть определенные пары объектов, которые не могут сравниваться друг с другом.

Почему я не могу исключить исключение из компаратора?

Я думаю Comparator.compare() не предназначен, чтобы бросить проверяемое исключение, потому что:

  1. предполагается, что любые элементы, которые вы бы хотели сравнить/сортировать всегда сопоставимы.

  2. , если Comparator.compare() может выбросить какой-то ожидаемый (т.проверено), то я могу представить пару нежелательных сценариев:

    a. сортировка может быть прервана, потому что там есть какой-то несравнимый объект - вероятным ответом является удаление несравнимого объекта (ов) и повторная сортировка

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

Это, конечно, просто моя гипотеза.

Как бы это решить?

я буду считать, что причина, по которой функция исключений возможно, что использует ваш Comparator.compare() бросает исключение является, потому что есть несравнимое объект в коллекции (как NaN Numberic значения). Варианты включают в себя:

  1. Отсортировать копию списка с несравнимым объектом (-ами).

  2. Выбросить исключение (исключение) для исключения сортировки. Не уверен, что бы вы сделали, кроме # 1 выше.

  3. Следуйте за приближением NaN и сделайте так, чтобы эти объекты выходили в начале или в конце.

    NaN значения, как правило, несравнимы с другими значениями, но в ходе сортировки компаратор определяет свое собственное полное упорядочение, так что значения NaN заканчиваются в конце сортированной коллекции.

    http://download.oracle.com/javase/1.4.2/docs/api/java/util/Arrays.html#sort (двойной [])

    ... The < соотношение не обеспечивает общий порядок для всех значений с плавающей запятой; ... значение NaN сравнивается не меньше, больше или равно любому значению с плавающей запятой, даже самому.

    ... Чтобы разрешить сортировку, этот метод использует общий порядок, наложенный Double.compareTo (java.lang.Double).

    ... Этот порядок отличается от отношения < тем, что ... NaN считается больше любого другого значения с плавающей запятой. Для целей сортировки все значения NaN считаются эквивалентными и равными.

    Чтобы сделать это, код вашего Comparator.compare(), что любой объект всегда бесподобен сравнивает больше, чем любой сопоставимый объект, и он всегда сравнивает равным с любым другим несравнимого объекта.

0

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

try { 
    // something 
} catch (Exception e) { 
    Thread.currentThread().stop(e); 
} 

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

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