Есть ли разница в скомпилированной Java с отключенными утверждениями между assert someBoolean (); и verifySomeBoolean (); где последний содержит утверждение?

У меня есть постусловие, которое я хочу регулярно проверять многими методами. Я почти уверен, что правильно использую assert < / a>, т.е. проверяю только что-то, чтобы убедиться, что мой код не делает ничего глупого, и я намерен через некоторое время отключить утверждения. Но я не уверен, что постусловие в том виде, в каком я его написал сейчас, - это именно то условие, которое мне всегда нужно. Я вложил это в метод. Но потом я столкнулся со следующей проблемой:

public class Foo
{
    public void doSomethingRisky()
    {
        //...
        assert someBoolean();
    }

    private boolean someBoolean()
    {
        return bar && baz;
    }
}

vs.

public class Foo
{
    public void doSomethingRisky()
    {
        //...
        verifySomeBoolean();
    }

    private void verifySomeBoolean()
    {
        assert bar && baz;
    }
}

Я знаю, что если я компилирую с отключенными утверждениями, предыдущий код не будет иметь проблем с производительностью, поскольку someBoolean() никогда не будет вызван. Но достаточно ли «умен» Java, чтобы при отключенных утверждениях вторая форма также не имела снижения производительности при отключенных утверждениях?

И, очевидно, более важный вопрос: какая практика лучше?

Мне нравится assert someBoolean(), потому что он явный, не подлежит повторной или неправильной интерпретации, но кажется, что другая форма может быть немного более надежным в будущем, потому что, возможно, я захочу расширить поведение verifySomeBoolean(), чтобы сделать что-то помимо утверждения такое же базовое логическое значение. Хотя мое чутье говорит, что если бы это было так, мне лучше перекодировать, чем пытаться подогнать старый код. Будем очень признательны за любые слова мудрых.


person Philip    schedule 09.11.2012    source источник


Ответы (1)


Я думал, вы не составили утверждений? Я думал, что они скомпилированы и могут быть включены только JVM с java -ea.

В этом случае JVM должна будет оптимизировать пустой вызов, когда -ea не используется. Но вы преждевременно оптимизируете. Сделайте код простым для понимания и написания. Затем оптимизируйте вторую. Вызов пустого метода не вызовет проблем с производительностью.

Обновление:

Что касается стиля, я бы подошел к утверждениям как можно ближе к проблеме. Я бы не хотел использовать assert в методе только для проверки.

Во-вторых, предварительные условия assert () и Guava имеют два разных применения. assert следует использовать для проверки того, что ваш мир остается тем миром, которым вы думали. Это скорее вещи типа assert (1+1 == 2). Вы не используете assert () для параметров вызываемого объекта. Вы используете assert для проверки того, что, как вы знаете, ДОЛЖНО быть правдой, но все равно проверяете это.

Похоже, что предварительные условия Guava - это то, что вам следует использовать. Это проверка ввода, которая используется для проверки соответствия контракту. Такие вещи, как: проверка нулевого аргумента, отрицательные числа, когда следует использовать только натуральные числа, правильно отформатированная строка и т. Д.

Таким образом, assert () - это «Дайте мне просто убедиться, что сила тяжести все еще здесь, даже если я знаю, что она есть», а предварительные условия: «Дайте мне убедиться, что я пытаюсь двигаться быстрее, чем позволяет полиция».

person Andrew T Finnell    schedule 09.11.2012
comment
Да, это то, что я имел в виду, упс. В любом случае, есть ли у вас какие-либо мысли по поводу двух вариантов, указанных выше, или альтернативного? Прочитав об этом подробнее, я на самом деле склоняюсь к использованию Guava Preconditions. - person Philip; 14.11.2012