[java] Java에서 두 개의 인수를 확인하십시오. null이 아니거나 우아하게 null입니다.

스프링 부트를 사용하여 이메일을 보내는 데 사용되는 쉘 프로젝트를 개발했습니다.

sendmail -from foo@bar.com -password  foobar -subject "hello world"  -to aaa@bbb.com

는 IF frompassword인수 누락, 나는 기본 발신자와 비밀번호, 예를 들어, 사용 noreply@bar.com123456.

따라서 사용자가 from인수를 전달하면 인수도 전달해야 password하며 그 반대도 마찬가지입니다. 즉, 둘 다 널이 아니거나 둘 다 널입니다.

이것을 우아하게 확인하려면 어떻게해야합니까?

이제 내 길은

if ((from != null && password == null) || (from == null && password != null)) {
    throw new RuntimeException("from and password either both exist or both not exist");
}



답변

^( XOR ) 연산자를 사용하는 방법이 있습니다 .

if (from == null ^ password == null) {
    // Use RuntimeException if you need to
    throw new IllegalArgumentException("message");
}

if하나의 변수가 null 인 경우 조건이 true가됩니다.

그러나 일반적으로 if예외 메시지가 다른 두 가지 조건 을 사용하는 것이 좋습니다 . 단일 조건을 사용하여 무엇이 잘못되었는지 정의 할 수 없습니다.

if ((from == null) && (password != null)) {
    throw new IllegalArgumentException("If from is null, password must be null");
}
if ((from != null) && (password == null)) {
    throw new IllegalArgumentException("If from is not null, password must not be null");
}

더 읽기 쉽고 이해하기 쉬우 며 약간의 추가 입력 만하면됩니다.


답변

음, 둘의 “nullity”조건이 같은지 아닌지 확인하려고하는 것 같습니다. 당신은 사용할 수 있습니다 :

if ((from == null) != (password == null))
{
    ...
}

또는 도우미 변수를 사용하여 더 명확하게 만드십시오.

boolean gotFrom = from != null;
boolean gotPassword = password != null;
if (gotFrom != gotPassword)
{
    ...
}


답변

개인적으로, 나는 읽기 쉽고 우아한 것을 선호합니다.

if (from != null && password == null) {
    throw new RuntimeException("-from given without -password");
}
if (from == null && password != null) {
    throw new RuntimeException("-password given without -from");
}


답변

서명을 사용하여 해당 기능을 2 개의 인수 메소드에 넣으십시오.

void assertBothNullOrBothNotNull(Object a, Object b) throws RuntimeException

이를 통해 실제 실제 방법으로 공간을 절약하고 더 읽기 쉽습니다. 약간 장황한 메소드 이름에는 문제가 없으며 매우 짧은 메소드에는 문제가 없습니다.


답변

Objects.isNull(Object)정적 가져 오기를 가정하면 Java 8 솔루션은을 사용합니다 .

if (isNull(from) != isNull(password)) {
    throw ...;
}

Java <8의 경우 (또는를 사용하지 않으려는 경우 Objects.isNull()) 고유 한 isNull()메소드를 쉽게 작성할 수 있습니다 .


답변

다음은 여러 null 검사에 대한 일반적인 솔루션입니다.

public static int nulls(Object... objs)
{
    int n = 0;
    for(Object obj : objs) if(obj == null) n++;
    return n;
}

public static void main (String[] args) throws java.lang.Exception
{
    String a = null;
    String b = "";
    String c = "Test";

    System.out.println (" "+nulls(a,b,c));
}

용도

// equivalent to (a==null & !(b==null|c==null) | .. | c==null & !(a==null|b==null))
if (nulls(a,b,c) == 1) { .. }

// equivalent to (a==null | b==null | c==null)
if (nulls(a,b,c) >= 1) { .. }

// equivalent to (a!=null | b!=null | c!=null)
if (nulls(a,b,c) < 3) { .. }

// equivalent to (a==null & b==null & c==null)
if (nulls(a,b,c) == 3) { .. }

// equivalent to (a!=null & b!=null & c!=null)
if (nulls(a,b,c) == 0) { .. }


답변

발신자와 비밀번호가 모두없는 경우 특별한 작업 (기본값 사용)을 원하므로 먼저 처리하십시오.
그 후에는 전자 우편을 보낼 발신자와 암호가 있어야합니다. 둘 중 하나라도 없으면 예외를 던집니다.

// use defaults if neither is provided
if ((from == null) && (password == null)) {
    from = DEFAULT_SENDER;
    password = DEFAULT_PASSWORD;
}

// we should have a sender and a password now
if (from == null) {
    throw new MissingSenderException();
}
if (password == null) {
    throw new MissingPasswordException();
}

추가 이점은 기본값 중 하나가 null이면 감지되는 것입니다.


데, 그런 말을 일반적으로 나는 그것이 당신이 필요로하는 사업자 인 경우 XOR의 사용은 허용해야한다고 생각합니다. 그것은 이다 때문에 난해한 컴파일러 버그의 작동 언어뿐만 아니라 몇 가지 트릭의 일부.
나는 한때 삼항 연산자가 너무 혼란스러워한다는 소를 발견했습니다 …