IT이야기

메서드 인수에 Not Null 주석 사용

cyworld 2022. 5. 29. 09:23
반응형

메서드 인수에 Not Null 주석 사용

이제 막 사용하기 시작했어요.@NotNullJava 8에서 주석을 달아 예기치 않은 결과를 얻을 수 있습니다.

다음과 같은 방법이 있습니다.

public List<Found> findStuff(@NotNull List<Searching> searchingList) {
    ... code here ...
}

인수 searching List의 null 값을 통과하는 JUnit 테스트를 작성했습니다.어떤 오류가 발생할 것으로 예상했는데 주석이 없는 것처럼 처리되었습니다.이것은 예상된 동작입니까?제가 알기로는, 이것은 당신이 보일러 플레이트의 늘 체크 코드를 쓰는 것을 생략할 수 있도록 하기 위한 것으로 알고 있습니다.

@NotNull이 정확히 무엇을 해야 하는지 설명해주시면 감사하겠습니다.

@Nullable그리고.@NotNull혼자서는 아무것도 할 수 없다.이들은 Documentation 툴로서 기능해야 합니다.

@Nullable주석을 사용하면 다음과 같은 경우 NPE 검사를 도입할 필요가 있음을 알 수 있습니다.

  1. null을 반환할 수 있는 호출 메서드.
  2. null일 수 있는 참조 해제 변수(필드, 로컬 변수, 파라미터).

@NotNull주석은 사실 다음을 선언하는 명시적 계약입니다.

  1. 메서드는 null을 반환할 수 없습니다.
  2. 변수(필드, 로컬 변수 및 매개 변수 등)는 null 값을 유지할 수 없습니다.

예를 들어, 다음과 같이 쓰는 대신:

/**
 * @param aX should not be null
 */
public void setX(final Object aX ) {
    // some code
}

다음을 사용할 수 있습니다.

public void setX(@NotNull final Object aX ) {
    // some code
}

또한.@NotNullConstraintValidators에 의해 자주 체크됩니다(봄 및 휴지 상태).

@NotNull주석 정의는 주석 자체를 제공하지 않기 때문에 주석 자체에서 어떠한 유효성 검사도 수행하지 않습니다.ConstraintValidator형식 참조.

자세한 내용은 다음을 참조하십시오.

  1. 빈 검증
  2. Not Null.java
  3. Constraint.java
  4. ConstraintValidator.java

전술한 바와 같이@NotNull그 자체로는 아무것도 할 수 없다.좋은 사용법@NotNull와 함께 사용할 수 있습니다.

public class Foo {
    private final Bar bar;

    public Foo(@NotNull Bar bar) {
        this.bar = Objects.requireNonNull(bar, "bar must not be null");
    }
}

만들기 위해서@NonNullLombok이 필요합니다.

https://projectlombok.org/features/NonNull

import lombok.NonNull;

다음 절차: 어떤 @NotNull Java 주석을 사용해야 합니까?

따라서 @NotNull은 태그일 뿐입니다.검증하려면 휴지 상태 검증기 jsr 303 같은 것을 사용해야 합니다.

ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
Validator validator = validatorFactory.getValidator();
 Set<ConstraintViolation<List<Searching>> violations = validator.validate(searchingList);

스프링을 사용하는 경우 클래스에 주석을 달아 강제로 검증을 수행할 수 있습니다.@Validated:

import org.springframework.validation.annotation.Validated;

자세한 내용은 여기를 참조하십시오.Javax @NotNull 주석 사용 현황

다음에서 사용할 수도 있습니다.projectlombok(알겠습니다.비특수)

독자적인 검증 주석과 검증자를 작성하려면 , 다음의 순서를 실행합니다.

ValidCardType.java(메서드/필드 작성에 대한 검토)

@Constraint(validatedBy = {CardTypeValidator.class})
@Documented
@Target( { ElementType.ANNOTATION_TYPE, ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidCardType {
    String message() default "Incorrect card type, should be among: \"MasterCard\" | \"Visa\"";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

그리고 검사를 트리거하는 검증자:CardTypeValidator.java:

public class CardTypeValidator implements ConstraintValidator<ValidCardType, String> {
    private static final String[] ALL_CARD_TYPES = {"MasterCard", "Visa"};

    @Override
    public void initialize(ValidCardType status) {
    }
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return (Arrays.asList(ALL_CARD_TYPES).contains(value));
    }
}

으로 체크할 수 요.@NotNull

테스트에서 메서드 검증을 테스트하려면 @Before 메서드로 메서드를 랩해야 합니다.

@Before
public void setUp() {
    this.classAutowiredWithFindStuffMethod = MethodValidationProxyFactory.createProxy(this.classAutowiredWithFindStuffMethod);
}

MethodValidationProxyFactory를 다음과 같이 설정합니다.

import org.springframework.context.support.StaticApplicationContext;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

public class MethodValidationProxyFactory {

private static final StaticApplicationContext ctx = new StaticApplicationContext();

static {
    MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
    processor.afterPropertiesSet(); // init advisor
    ctx.getBeanFactory()
            .addBeanPostProcessor(processor);
}

@SuppressWarnings("unchecked")
public static <T> T createProxy(T instance) {

    return (T) ctx.getAutowireCapableBeanFactory()
            .applyBeanPostProcessorsAfterInitialization(instance, instance.getClass()
                    .getName());
}

}

그런 다음 테스트를 추가합니다.

@Test
public void findingNullStuff() {
 assertThatExceptionOfType(ConstraintViolationException.class).isThrownBy(() -> this.classAutowiredWithFindStuffMethod.findStuff(null));

}
I resolved it with

@JsonSetter(nulls = Nulls.AS_EMPTY)
@NotBlank
public String myString;

Request Json:
{
  myString=null
}
 Response:
 error must not be blank

언급URL : https://stackoverflow.com/questions/34094039/using-notnull-annotation-in-method-argument

반응형