@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
'๐ Java&Spring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
ํจ์ํ ์ธํฐํ์ด์ค (Functional Interface) (2) | 2023.11.25 |
---|---|
Intellij) JUnit5 ์ค์ ํ ์ฌ๋ ๊ด (0) | 2023.07.27 |
Error) java: class, interface, or enum expected ํด๊ฒฐ (0) | 2023.06.26 |
๐ธ startsWith()/endWith() ๋ฌธ์์ด์ ์์๊ณผ ๋ (0) | 2023.04.04 |
@JsonProperty์ @JsonNaming (0) | 2023.03.17 |