В Java, что лучший способ продолжиться должно вызвать функцию, пока никакое исключение не выдается?

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

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

6
задан Eric 29 October 2009 в 11:18
поделиться

8 ответов

Я удивлен, прочитав некоторые ответы в этой ветке, потому что именно этот сценарий является причиной существования проверенных исключений. Вы можете сделать что-то вроде:

private final static int MAX_RETRY_COUNT = 5;

//...

int retryCount = 0;
int angle = -1;

while(true)
{
    try
    {
        angle = getAngle();
        break;
    }
    catch(NoAngleException e)
    {
        if(retryCount > MAX_RETRY_COUNT)
        {
            throw new RuntimeException("Could not execute getAngle().", e);
        }

        // log error, warning, etc.

        retryCount++;
        continue;
    }
}

// now you have a valid angle

Предполагается, что за это время что-то изменилось вне процесса. Обычно что-то вроде этого будет сделано для переподключения:

private final static int MAX_RETRY_COUNT = 5;

//...

int retryCount = 0;
Object connection = null;

while(true)
{
    try
    {
        connection = getConnection();
        break;
    }
    catch(ConnectionException e)
    {
        if(retryCount > MAX_RETRY_COUNT)
        {
            throw new RuntimeException("Could not execute getConnection().", e);
        }

        try
        {
            TimeUnit.SECONDS.sleep(15);
        }
        catch (InterruptedException ie)
        {
            Thread.currentThread().interrupt();
            // handle appropriately
        }

        // log error, warning, etc.

        retryCount++;
        continue;
    }
}

// now you have a valid connection
8
ответ дан 8 December 2019 в 05:55
поделиться

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

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

5
ответ дан 8 December 2019 в 05:55
поделиться

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

2
ответ дан 8 December 2019 в 05:55
поделиться

В конце концов я решил вернуть значение NaN, так как это предотвращает небрежное использование Integer.MIN_VALUE где-то еще.

public float getAngle(boolean blocking)
{
    while(true)
    {
        int dir = getDirection();
        if(dir == 0 && !blocking)
            return Float.NaN;
        else
            return (dir - 5) * 30;
    }
}
1
ответ дан 8 December 2019 в 05:55
поделиться

Никогда не используйте исключения для обработки логики потока в коде.

как предлагается, сначала проверьте, почему вы иногда получаете выполнение

0
ответ дан 8 December 2019 в 05:55
поделиться

Вы хотите вызывать метод, пока он генерирует исключение?

Это не программирование. Вам следует использовать отладчик и взглянуть на реальную проблему.

И вы никогда не должны перехватывать исключение без какого-либо сообщения или регистрации!

3
ответ дан 8 December 2019 в 05:55
поделиться

Не могли бы вы использовать рекурсию? т.е.

public int getAngleBlocking()
{
        int angle;
        try
        {
                angle = getAngle();
                return angle;
        }
        catch(NoAngleException e)
        {
               return getAngleBlocking();
        }
    }
}
3
ответ дан 8 December 2019 в 05:55
поделиться

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

Иногда, конечно, это невозможно, либо потому, что класс не принадлежит вам, либо невозможно двойное использование возвращаемого типа как результата, так и статуса ошибки.

Например, в вашем случае, предполагая, что все целые (отрицательные и 0) градусы являются возможными углами, вы не сможете вернуть значение типа int, которое указывает на ошибку и отличается от допустимого значения угла.

Но давайте предположим, что ваши допустимые углы находятся в диапазоне -360 -> 360 (или эквивалент в радианах). Тогда вам действительно стоит подумать о следующем:

// assuming this ..
public static final int NO_ANGLE_ERROR = Integer.MIN_VALUE; 

// do this
public int getAngleBlocking()
{
    int angle;
    do {
       angle = getAngle();
    }while(angle == NO_ANGLE_ERROR);
}
0
ответ дан 8 December 2019 в 05:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: