๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

๐Ÿ“– Java&Spring

NonNull ์‚ฌ๋ž‘...์‚ฌ...์‚ฌ...๋ž‘... ๊ทธ๋ƒฅ ์ข‹์•„ํ•ฉ๋‹ˆ๋‹ค.

๋ฌด๋„ ์‚ฌ๋ž‘ํ•ด์š”

 

 

@NonNull์€ ์‚ฌ์šฉ์ž์—๊ฒŒ null ์ฒดํฌ ์ž˜ํ•˜์‹ญ์‡ผ ํ•˜๊ณ  ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ๋Š” ์–ด๋…ธํ…Œ์ด์…˜์ž…๋‹ˆ๋‹ค

 

๋ณดํ†ต ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์šฉ๋„๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค

Record component / ํ•จ์ˆ˜์˜ ํŒŒ๋ผ๋ฏธํ„ฐ / ์ƒ์„ฑ์ž์˜ ํŒŒ๋ผ๋ฏธํ„ฐ

 

์š”๋ ‡๊ฒŒ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

 

public void doSomething(@NonNull String input) {
    // input์€ null์ผ ์ˆ˜ ์—†์Œ
    // ์—ฌ๊ธฐ์„œ ์•ˆ์ „ํ•˜๊ฒŒ input์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ!!
}

 

 

@NonNull์„ ์•ˆ ์“ฐ๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ํ–ˆ๊ฒ ์ฅฌ?

์‚ฌ์‹ค ์”จ์Ÿ์ด๋Š” ์•„๋ž˜์˜ ์ฝ”๋“œ๊ฐ€ ๋” ์ต์ˆ™ํ•˜์ง€๋งŒ ๐Ÿ˜’

ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ๋ณด๋ฉด if ๋ฌธ ๋งŒ๋“ค์–ด์•ผ ์ง์„ฑ์ด ํ’€๋ฆฌ๋Š” ํŽธ.

 

public void doSomething(String input) {
    // input์€ null์ด๋ฉด ์•„๋‹ˆ๋œ๋‹ค..
    if( input == null ) {
    	return;
    }
}

 

 

@NonNull์„ ์“ฐ๋ฉด ๊ทธ๋Ÿผ ๋ฌด์—‡์ด ์ข‹์„๊นŒ?

์œ„์— ์˜ˆ์‹œ์—์„œ ๋ณด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ์ผ๋‹จ ๊ฐ€๋…์„ฑ์ด ์ข‹๋‹ค.

๊ทธ๋ฆฌ๊ณ  null ๊ด€๋ จ ๋ฒ„๊ทธ๋ฅผ ๋ฐฉ์ง€ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋œ๋‹ค.

 


 

๊ฐœ์ธ์ ์ธ ์˜๊ฒฌ์œผ๋กœ...

๋‚˜๋Š” ๋‹ค๋ฅธ ๊ฐœ๋ฐœ์ž์˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ๋‚˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์ œ์ผ ๋จผ์ € ๋ณด๊ฒŒ ๋œ๋‹ค

์™œ๋ƒ๊ตฌ์š”?

์ €๋„ ๊ทธ๋ ‡๊ฒŒ ๋˜๊ณ  ์‹ถ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค...

์˜ฌ๋ฐ”๋ฅธ output์„ ์œ„ํ•ด ์˜ฌ๋ฐ”๋ฅธ input์ธ์ง€ ์ž˜ ํ™•์ธํ•ฉ์‹œ๋‹ค์š”

 


@NonNull๋กœ null ์ฒดํฌ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ•

 

๊ทธ๋Ÿผ ํŒŒ๋ผ๋ฏธํ„ฐ null-check ์‹œ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š๋ƒ.

 

1. java.lang.NullPointerException ์˜ˆ์™ธ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ

default ์˜ˆ์™ธ๋Š” NullPointerException์ด๋‹ค

import lombok.NonNull;

public class NonNullExample extends Something {
  private String name;
  
  public NonNullExample(@NonNull Person person) {
    super("Hello");
    /* ์•„๋ž˜ ํŒŒ๋ผ๋ฏธํ„ฐ ์ฒดํฌ๋ฅผ ์ƒ๋žตํ•ด๋„ ๋œ๋‹ค
    if (person == null) {
      throw new NullPointerException("person is marked non-null but is null");
    }
    */
    this.name = person.getName();
  }
}

 


ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ถ”๊ฐ€ ์ฒจ๋ถ€

 

    static public class NonNullExample {
        private String name;

        public NonNullExample(@NonNull Person person) {
            this.name = person.getName();
        }
    }

    @Data
    static public class Person {
        String name;
    }

    @Test
    @DisplayName("Person ๊ฐ์ฒด๊ฐ€ null์ผ ๋•Œ NPE ์˜ˆ์™ธ์ฒ˜๋ฆฌ ํ™•์ธ")
    public void paramCheck_npe() {
        Throwable throwable = Assertions.assertThrows(NullPointerException.class, () -> new NonNullExample(null));
        assertEquals("person", throwable.getMessage());
    }

 

2. IllegalArgumentException์œผ๋กœ ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€ ๋ฐ”๊พธ๊ธฐ

IllegalArgumentException์„ ์‚ฌ์šฉํ•˜๋ฉด ์˜ˆ์™ธ ๋ฉ”์‹œ์ง€๋ฅผ ๋‹ค๋ฅด๊ฒŒ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค

์–˜๋Š” ์‚ฌ์šฉํ•˜๋ ค๋ฉด lombok ์„ค์ •์„ ํ•ด์ค˜์•ผํ•œ๋‹น

 

lombok.nonNull.exceptionType = IllegalArgumentException

 

 

3. Assertion ์‚ฌ์šฉํ•˜๊ธฐ

import lombok.NonNull;
import lombok.core.configuration.NonNullEx;
import lombok.core.configuration.NonNullEx.MethodName;

@NonNullEx(MethodName.ASSERT)
public class NonNullExample {
    private String name;

    public NonNullExample(@NonNull String name) {
        this.name = name;
    }
}

// ์ƒ์„ฑ๋œ ์ฝ”๋“œ:
public NonNullExample(@NonNull String name) {
    assert name != null : "name is marked non-null but is null";
    this.name = name;
}

 

 

4. Objects.requireNonNull ํ•จ์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ

java 7์— ์ถ”๊ฐ€๋œ ์นœ๊ตฌ์ธ๋ฐ Null ์ฒดํฌ๋ฅผ ์œ„ํ•œ ํ•จ์ˆ˜๋‹ค

ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ž…๋ ฅ๋œ ๊ฐ’์ด๋ฉด NullPointerException์„ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค

 

// ์ƒ์„ฑ๋œ ์ฝ”๋“œ (JDK๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ):
public NonNullExample(@NonNull String name) {
    java.util.Objects.requireNonNull(name, "name is marked non-null but is null");
    this.name = name;
}

 

 

5. @NonNull Flag ์„ค์ •ํ•˜๊ธฐ

์•„๋ž˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ WARNING์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ์•„๋ž˜ ๊ฒฝ์šฐ์— ๊ฒฝ๊ณ ๋ฅผ ํ™œ์„ฑํ™”ํ•ด์„œ

๊ฐœ๋ฐœ์ž๋“ค์˜ ์‹ค์ˆ˜๋ฅผ ์ค„์—ฌ์ค€๋‹ค๊ณ  ํ•œ๋‹ค

 

- ํ•„๋“œ/๋งค๊ฐœ๋ณ€์ˆ˜/๋ฆฌํ„ด ํƒ€์ž…์— ์ ์šฉ ์•ˆ ํ•œ ์ž˜๋ชป๋œ ๊ฒฝ์šฐ

- ์ ์ ˆํ•œ ์œ„์น˜๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ

- ๊ทœ์น™ ์œ„๋ฐ˜ํ•œ ๊ฒฝ์šฐ

 

import lombok.NonNull;

@NonNullEx(FlagUsage.WARNING)
public class NonNullExample {
    private String name;

    public void processName(@NonNull String name) {
        // ์ด ๋ถ€๋ถ„์—์„œ ๊ฒฝ๊ณ ๊ฐ€ ๋ฐœ์ƒํ•œ๋“œ์•„
        System.out.println("Name: " + name);
    }
}

 


์ฐธ๊ณ ์ž๋ฃŒ

 

https://projectlombok.org/features/NonNull

 

@NonNull

 

projectlombok.org