Переопределить fillInStackTrace для потока управления / производительности - PullRequest
4 голосов
/ 03 декабря 2009

Примечание: хотя на первый взгляд похоже, это не дубликат Переопределение fillInStackTrace для стандартных исключений JVM

Что вы думаете о переопределении fillInStackTrace для проверенных исключений для возврата null?

Преимущества:

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

Самым большим недостатком является просто то, что это не стандартная практика.

Но единственный способ сделать что-то подобное:

  1. возвращает ноль или «специальное значение» назад (например, -1), чтобы показать, что что-то пошло не так.
  2. изменение вызываемого объекта для возврата составного объекта со значением и кодом ошибки, а также вызов вызывающего вызывающего объекта для проверки того, что произошло.

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

Очевидно, RIFE использует эту технику:

http://www.rifers.org/
http://cretesoft.com/archive/newsletter.do?issue=129

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

    //standard
    int i = "foo".indexOf('f');
    if (i<0){
      System.out.println("found f");
    } else {
      System.out.println("no f here");
    }
    //example
    try {
      "foo".indexOf('f');
      System.out.println("found f");
    } catch (NotFound e) {
      System.out.println("no f here");
    }

Ответы [ 2 ]

3 голосов
/ 03 декабря 2009

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

Моя общая мысль состояла бы в том, что есть состояние неудачи, когда вы пытаетесь вернуть дерево. Если бы это состояние было установлено в общем объекте, то состояние было бы просто там для запроса.

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

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

Пример из комментариев: В комментарии asker использовал indexOf в качестве примера - способ, которым он возвращает два значения в int. Это всегда приведет к довольно простому коду:

int pos=str.indexOf('a');
if(pos < 0) // Not obvious from code--should comment...
    System.out.println("Fail");
else
    //Do something with pos...

Он предлагает решить эту проблему с исключением, которое приведет к такому коду:

try {
    int pos=str.indexOf('a');
    //Do something with pos...
} catch(CharacterNotFoundInStringException e) {
    System.out.println("Fail");
}

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

Мое предложение может быть также для создания нового класса, но кодируйте его следующим образом:

Position pos=str.indexOf('a');
if(!pos.characterFound())
    System.out.println("Fail");
else
    // do something with pos.location();

Самодокументирование, быстрее (выпадение стека с исключениями всегда медленнее) и т. Д.

Но, как я говорил изначально, самое большое преимущество - это новый класс "pos". Это, вероятно, окажется весьма полезным. Фактически, вместо использования pos.location, вы можете фактически переместить код из предложения "else" внутри метода в "pos", полностью удалив его.

Поскольку он может содержать бизнес-логику, этот метод в Position может фактически выполняться самим вызовом .indexOf, полностью исключая оператор if вокруг вызова.

Это не имеет особого смысла для «универсальных» библиотечных методов, таких как indexOf, жаль, но методы SDK действительно сложно реализовать в правильном ОО, но в вашей собственной бизнес-логике вы почти наверняка найдете это новый класс "Позиция" очень полезен в будущем.

1 голос
/ 03 декабря 2009

Я думаю, что все в порядке. Иногда у тебя нет выбора. Но я считаю, что код «if-else для возвращаемого значения» обычно легче писать и читать, чем код «try-catch on exception».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...