В чем разница между этими кодами? Почему у них разные выходы?

это может показаться ничтожным выбором ...

... но имейте в виду, что ни одно из них:

  • Findbugs
  • Валидация боба (JSR303)
  • Проверка бина 2.0 (JSR380)

происходит во время компиляции, что очень важно в этом обсуждении.

Проверка бонуса происходит во время выполнения и, как таковая, требует явного вызова в коде или управляемой среде, неявно делает это (например, Spring или JavaEE), создавая и вызывая валидаторы.

FindBugs - это статический анализатор байт-кода и, следовательно, после компиляции. Он использует умную эвристику, но не выполняет код и поэтому не на 100% водонепроницаем. В вашем случае он следил за проверкой недействительности только в мелком корпусе и пропустил строителя.

Также обратите внимание, что вручную создавая компоновщик и добавляя необходимые аннотации @NotNull, FindBugs не включались бы, если бы вы не назначали какое-либо значение, как против назначения null. Еще один пробел - отражение и десериализация.

Я понимаю, что вы хотели бы, чтобы контракт, выраженный в аннотациях проверки (например, @NotNull), был проверен как можно скорее.

способ сделать это на SomeClassBuilder.build() (все еще время работы!), но это немного связано и требует создания пользовательского построителя:

, возможно, его можно было бы сделать общим для размещения многих классов - somoeone, пожалуйста, отредактируйте!

@Builder
class SomeObject {
  @NonNull String mandatoryField1;
  @NonNull String mandatoryField2;
  Integer optionalField;
  ...

  public static SomeObjectBuilder builder() { //class name convention by Lombok
    return new CustomBuilder();
  }

  public static class CustomBuilder extends SomeObjectBuilder {
    private static ValidationFactory vf = Validation.buildDefaultValidationFactory();
    private Validator validator = vf.getValidator();

    @Overrride
    public SomeObject build() {
      SomeObject result = super.build();
      validateObject(result);
      return result;
    }

    private void validateObject(Object object) {
      //if object is null throw new IllegalArgException or ValidationException
      Set<ConstraintVioletion<Object>> violations = validator.validate(object);

      if (violations.size() > 0) { 
        //iterate through violations and each one has getMessage(), getPropertyPath() 
        // - to build up detailed exception message listing all violations
        [...]
        throw new ValidationException(messageWithAllViolations) }

    }        
}
0
задан Mad Physicist 19 January 2019 в 05:27
поделиться

3 ответа

str() создает строку, подобную "['first', 'second', 'third', 'fourth']".

И s.join() обрабатывают строку как массив символов. Затем он помещает '/' между каждым элементом в массиве.

0
ответ дан Some programmer dude 19 January 2019 в 05:27
поделиться

str преобразует свой аргумент в строковое представление. Строковое представление списка представляет собой одну строку, начинающуюся с открывающей квадратной скобки и заканчивающуюся закрывающей. Элементы между ними конвертируются с использованием repr и разделяются с помощью ,. Эта строка сама по себе является итерацией символов. Таким образом, join поместит / между каждым элементом итерируемого, то есть между каждым символом строки.

Эквивалентом вашего первого кода будет преобразование каждого строкового элемента списка в отдельную строку:

s.join(str(x) for x in list)

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

Для произвольных списков подход, показанный здесь , лучше , чем просто использование s.join(list), потому что join требует, чтобы все элементы итерируемого объекта были равны str s, но не предпринимал попыток преобразования их, как говорят print. Вместо этого он поднимает TypeError, когда встречает не str.

Другим, менее питонным, но, тем не менее, очень распространенным способом выражения того же преобразования является

s.join(map(str, list))

И, конечно, вставьте обязательное предостережение против именования переменных после общих встроенных функций здесь для себя. [1121 ]

0
ответ дан Mad Physicist 19 January 2019 в 05:27
поделиться

Функция join - это строковый метод, который возвращает строку, объединенную с элементами итерируемого.

Теперь, в первом случае:

list_1 = ['first', 'second', 'third', 'fourth'] #I changed the name to list_1 as list is a keyword
s = '/'
newList = s.join(list_1)
print(newList)

Каждая строка в списке является итеративной, поэтому объедините выходные данные, объединив все элементы списка, добавив '/' между каждым элементом. [1110 ]

Во втором случае:

list_1 = ['first', 'second', 'third', 'fourth']
s = '/'
newList = s.join(str(list_1))
print(newList)

Так как, str преобразует весь список, включая фигурные скобки [ и ], в виде строки. Благодаря этому каждый символ в новой строке становится итеративным, и объединение возвращает новую строку, добавляя '/' между каждым элементом.

0
ответ дан Jay 19 January 2019 в 05:27
поделиться
Другие вопросы по тегам:

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