происходит во время компиляции, что очень важно в этом обсуждении.
Проверка бонуса происходит во время выполнения и, как таковая, требует явного вызова в коде или управляемой среде, неявно делает это (например, 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) }
}
}
str()
создает строку, подобную "['first', 'second', 'third', 'fourth']"
.
И s.join()
обрабатывают строку как массив символов. Затем он помещает '/'
между каждым элементом в массиве.
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 ]
Функция 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
преобразует весь список, включая фигурные скобки [
и ]
, в виде строки. Благодаря этому каждый символ в новой строке становится итеративным, и объединение возвращает новую строку, добавляя '/'
между каждым элементом.