โ ๊ฐ๋ฐ์๋ค์ ๊ดด๋กญํ๋ ์๋ฐ NULL ํํค์น๊ธฐ
๊ฐ๋ฐ์์ ์์ํ ์์ NULL
null ์ด๋ผ๋ ๋จ์ด๋ ํ๋ก๊ทธ๋๋ฐ์ ๋ฐฐ์๋ณด๋ฉด ๋น ๋ฅด๋ ๋ฆ๋ ๋ฐ๋์ ์ ํ๊ฒ ๋๋ ๋ ์์ด๋ค. ํ๋ก๊ทธ๋๋ฐ์ ๊ฐ ์ ํ ์ฌ๋๋ค์ null์ ๊ทธ์ '๊ฐ์ด ์๋ ๊ฒ' ์ผ๋ก ์ธ์ฐ๊ณ ๋์ด๊ฐ๋ฒ๋ฆฐ๋ค. ์ฌ์ง์ด null์ ๋ถ์ ์ ๋ป์ผ๋ก 0 ์ด๋ ๊ณต๋ฐฑ ๊ทธ๋ฆฌ๊ณ false ์ ๋์ผ์ ์์ ๋๊ณ ์๊ฐํ๊ธฐ๋ ํ๋ค. ๋น์ฐํ ์ด๋ ์๋ชป๋ ์ ์ ์ด๋ค.
๊ทธ์ ๊ฐ์ด ์๋ค๋ ํํ์ผ ๋ฟ์ธ๋ฐ ๊ฐ๋ฐ์์ ์์ํ ์์ ๋ผ๋ ๋ญ๋ ๋ผ๋ ํํ์ ์ฐ๋ ์ด์ ๋, ๊ฐ๋ฐ์๋ค์ด null์ ๋ง์ฃผํ๋ ๊ฒฝ์ฐ๊ฐ ํ๋ก๊ทธ๋จ ์คํ์ค์ ์๋ฌ ๋ฉ์ธ์ง(NullPointerException) ๋ก ์ธํด ์๋์ ํ๋ ํ๋ก๊ทธ๋จ์ด ์ฃฝ์ด๋ฒ๋ ค ์์ธ์ ์ฐพ๋๋ผ ์ฌํ ๊ณ ์์ ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์ฐ์ NULL ์ด๋ผ๋ ๊ฐ๋ ์, ์๊ตญ์ ์ปดํจํฐ ๊ณผํ์์ธ ํ ๋ ํธ์ด(Tony Hoare)๊ฐ 1965๋ ์ ์๊ณจ(ALGOL W)์ด๋ผ๋ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ฅผ ์ค๊ณํ๋ฉด์ ์ฒ์ ๋ฑ์ฅํ๋ค. ๋น์์ ๊ทธ๋ '๊ฐ์ด ์กด์ฌํ์ง ์๋ ์ํฉ' ์ ํธ๋ฆฌํ๊ฒ ํํํ๊ธฐ ์ํด null ์ด๋ผ๋ ๊ฐ๋ ๊ณ ์ํ๋ค. ํ์ง๋ง ์๊ฐ์ด ํ๋ฌ ํ ์ํํธ์จ์ด ์ปจํผ๋ฐ์ค์์ ๊ทธ๋ ์์ ์ด ๊ณ ์ํ null ์ฐธ์กฐ๋ฅผ '10์ต ๋ฌ๋ฌ์ง๋ฆฌ ์ค์' ๋ผ๊ณ ํํํ๋ฉฐ null ์ฐธ์กฐ๋ฅผ ๋ง๋ ๊ฒ์ ํํํ๋ค๊ณ ํ ๋กํ์๋ค. ๋จ์ํ ์๋ ๊ฐ์ ํํํ๊ธฐ ์ํ null ์ฐธ์กฐ ๊ฐ๋ ์ด ์ด๋ก ์ธํด ์๋ง์ ์ค๋ฅ, ์ทจ์ฝ์ฑ ๋ฐ ์์คํ ์ถฉ๋์ด ์๊ธฐ๊ณ ํผํด๊ฐ ๋ง๋ํ๊ธฐ ๋๋ฌธ์ด๋ค.
์๋ฐ์ NULL ํํค์น๊ธฐ
์ฌ์ค ์๋ฐ์์์ ์ด null ์ด๋ผ๋ ๋
์์ ๊ต์ฅํ ์ฌ์คํ ๋
์์ด๋ค. ์๋ํ๋ฉด ๊ฐ์ด ์๋ค๋ ๊ฑธ ํํํ๊ธฐ ์ํ ํค์๋์ธ๋ฐ, int ๋ char๊ฐ์ ๋ฒ์ฉ์ ์ธ ํ์
์ ๋์
ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ด๋ค ๊ฐ์ primitive ์๋ฃํ์ผ ๊ฒฝ์ฐ ๊ฐ๋ณ์ ์ผ๋ก 0์ด๋ ๊ณต๋ฐฑ ๊ฐ์ ๊ฒ์ผ๋ก ๊ฐ์ด ์๋ค๋ ๊ฒ์ ๊ฐ์ ์ ์ผ๋ก ํํํ๊ธฐ ๋๋ฌธ์ null์ ๋์ ํ ์ ์๋ ๊ฒ์ด๋ค. ๋ฐ๋ฉด ์๋ฐ์ reference ํ์ ๊ฐ์ ๊ฒฝ์ฐ ๊ฐ์ด ์๊ฑฐ๋ ๊ธฐ๋ณธ๊ฐ์ null๋ก ์ง์ ํ๋ค.
primitive๋ 0์ด๋ false ๊ทธ๋ฆฌ๊ณ reference๋ null ์ด๋ฐ์์ผ๋ก ์ฃผ์ ์ ์๊ธฐ ํ๋๊ฒ๋ ๋์์ง๋ ์์ง๋ง, ์ reference๋ null๋ก ๋๋์ง ์ด์ ๋ฅผ ์๋ค๋ฉด ์ถํ์ ์์ ์ ํ๋ก๊ทธ๋จ์ด null ๊ด๋ จ ๋ฌธ์ ๊ฐ ํฐ์ก์๋ ์ด๋ฅผ ์ ์ถํ๋๋ฐ ๋์์ด ๋๋ ๊ฐ๋จํ๊ฒ ์์๋ณด์.
null์ ์ ํํ ์๋ฏธ
C์ธ์ด์์๋ ์์ฑ๋ ๋ฉ๋ชจ๋ฆฌ์ ์ฃผ์๋ฅผ 'ํฌ์ธํฐ'๋ผ๋ ๊ฒ์ด ๊ฐ๋ฆฌํค๊ฒ ๋์ด ํฌ์ธํฐ๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. ํฌ์ธํฐ๋ ๊ฐ๋จํ ๋งํ๋ฉด ์ด๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋ ์ฃผ์๋ฅผ ์ ์ฅํ๋ ๋ณ์์ด๋ค. ๊ทธ๋ฐ๋ฐ ๋ง์ผ ํฌ์ธํฐ ๋ณ์๋ฅผ ์ ์ธ ๋ฐ ์ด๊ธฐํ๋ฅผ ํ๋ฒ์ ์งํํ์ง ์๊ณ ์ ์ธ๋ง ํ๋ค๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
int๋ double ํ์
๊ฐ์ ๊ฒฝ์ฐ ์ด๊ธฐ๊ฐ์ผ๋ก 0์ด ๋ค์ด๊ฐ๋ค๋ ๊ฒ์ ๋ชจ๋๋ค ์๋ ์ฌ์ค์ด๋ค. ์์๊ฐ์ ์์ฒด์ ์ผ๋ก ์ ์ฅํ๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๋ค. ๋ฐ๋ฉด ํฌ์ธํฐ ๋ณ์๋ ์๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ์ด ๋ค์ด์์ผ ๋์ง๋ง ์ด๊ธฐํ๋ฅผ ์ํ ๊ฒฝ์ฐ 0์ด๋ false ๊ฐ์ ์ฃผ์์ ๋ฌด(็ก)์ ๊ฐ์ ํํํด์ผ ํ๋๋ฐ, ๊ทธ ํํํ๋ ํค์๋๊ฐ ๋ฐ๋ก NULL ์ธ ๊ฒ์ด๋ค.
์ฆ, NULL์ ์ฃผ์๊ฐ์ด ์๋ ๊ฒ(์๋ฌด๊ฒ๋ ๊ฐ๋ฆฌํค๊ณ ์์ง ์๋ค๋ ๊ฒ)์ ๋งํ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฐ๋ฐ ์๋ฐ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ฉด์ ํฌ์ธํฐ๋ฅผ ๋ค๋ฃฐ ์ผ๋, ๋ค์ ์ผ๋ ์์์ ๊ฒ์ด๋ค. ์๋ํ๋ฉด ์ด๋ ์๋ฐ์์ ํฌ์ธํฐ ๊ฐ๋ ์ ์์ ์ ๊ทธ๋ฐ๊ฒ์ด ์๋๋ผ, ๊ฐ๋ฐ ํธ์์ฑ์ ์ํด ์ฒ ์ ํ ์จ๊ฒผ๊ธฐ ๋๋ฌธ์ด๋ค. ์ฌ์ค ์๋ฐ์ ๋ฐฐ์ด, ๊ฐ์ฒด, ์คํธ๋ง ๊ฐ์ reference ํ์ ์ ๋ชจ๋ ์ฐธ์กฐ(ํฌ์ธํฐ) ๋ณ์์ธ ์ ์ด๋ค.
์๋ฐ์ ์ฐธ์กฐ ๋ณ์์ ํฌ์ธํฐ์ ์ ํํ ๊ณตํต์ ๊ณผ ์ฐจ์ด์ ์ ๋๋ค ์ฃผ์ ์์ ๋ฉ๋ชจ๋ฆฌ์ ์ง์ ์ ๊ทผํ๋ค๋ ๊ณตํต์ ์ ๊ฐ์ง์ง๋ง, ์ฐธ์กฐ ๋ณ์๋ ์ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํธ๋ค๋ง ํ ์ ์์ด ์ฃผ์๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ค.
๋ฐ๋ฉด ํฌ์ธํฐ๋ ์ฃผ์๊ฐ์ ๋ณ๊ฒฝ์์ผ ์ต์ฐ์ฑ๊ณผ ์ฑ๋ฅ์ ํฅ์ ์ํฌ์ ์์ง๋ง ๋์ ์์ ์ฑ์ด ๋จ์ด์ง๋ค๋ ํน์ง์ด ์๋ค.
์ฆ, ์๋ฐ์ ์ฐธ์กฐ ๋ณ์๋ ๋ฉ๋ชจ๋ฆฌ ์ฃผ์๊ฐ์ ๋ณ๊ฒฝํ ์ ์๋ ํฌ์ธํฐ๋ผ๊ณ ๋ด๋ ๋๋ค. ์ด๋ฌํ ํน์ฑ์ ๊ธฐ์ตํ๋ฉด์ ๋ค์ ์๋ฐ ํ๋ก๊ทธ๋๋ฐ์์์ null ์ฒ๋ฆฌ๊ฐ ์ด๋ป๊ฒ ๋๋์ง ๋ณด์.
null ๊ณผ ์ฐธ์กฐํ ํ๋์ ๊ด๊ณ
๋ค์ ๋ณต์ตํ์๋ฉด, ๋ชจ๋ ์์ํ ํ์
(Primitive type) ์ ๋ฐ๋ก ๊ฐ์ ์ด๊ธฐํ ํ์ง ์์์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ์ผ๋ก ๊ฐ๊ฒ ๋๋ default ๊ฐ์ด ์๋ค. ์๋ฅผ ๋ค์ด ๊ธฐ๋ณธํ ํ์
์ธ boolean ํ์
์ false, ์ ์ํ int๋ 0์ ๊ฐ๋๋ค.
ํ์ง๋ง ์ฐธ์กฐํ ํ์ (Reference type)์ default ๊ฐ์ผ๋ก null์ ๊ฐ๊ฒ ๋๋ค. ์๋ํ๋ฉด ์ฐธ์กฐ๋ณ์๊ฐ ์ง์ญ๋ณ์๋ก ์ ์ธ๋ ๊ฒฝ์ฐ ์ ์ธ๊ณผ ๋์์ ์ด๊ธฐํ๋์ด์ผ ๋๋๋ฐ, ์ ์ธํ ๋ ์ฐธ์กฐ๋ณ์๊ฐ ๊ฐ๋ฆฌํฌ ๊ฐ์ฒด์ ์ฃผ์๊ฐ ๊ฒฐ์ ๋์ง ์์๊ธฐ ๋๋ฌธ์ ์ด๋ฅผ ํํํ๊ธฐ ์ํ ํค์๋๋ก null์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ด๋ค.
class Test {
int i; // Primitive type
Integer ii; // Reference type
}
Test t = new Test(); // ๋ฐ๋ก ์ด๊ธฐํ ์์ด ๋ฐ๋ก ๊ฐ์ฒด ์์ฑ
System.out.println(t.i); // 0
System.out.println(t.ii); // null
๋ฐ๋ก ์์์ C ์ธ์ด์ ํฌ์ธํฐ์ ๋ํด ์ค๋ช ํ ๋ null์ ํฌ์ธํฐ ๋ณ์์์ ๋ค๋ค์ง๋ ์ฃผ์๊ฐ์ ๊ฐ์ง ์๋ ํค์๋๋ผ ๋งํ๋ฐ๊ฐ ์๋ค. ์ด๋ฅผ ์ธ์ฉํ๋ค๋ฉด null์ ์๋ฐ์ ์ฐธ์กฐ ๋ณ์์๋ง ๋ค์ด๊ฐ ์ ์๋ ๊ฐ์ด๋ผ๋ ๋ง์ด ๋๋ค.
๊ทธ๋์ ์ค์ ๋ก null์ ์์ํ(Primitive type) ํ์ ์ ๋ณ์์ ํ ๋นํ๊ฒ ๋๋ฉด ์ปดํ์ผ ์๋ฌ(NullPointerException)๊ฐ ๋ฐ์ํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฐ๋ฐ์๋ฅผ ๊ดด๋กญ๊ฒ ๋ง๋๋ ์์ธ์ค ํ๋์ด๋ค.
int i = null; // ์ปดํ์ผ ์ค๋ฅ ๋ฐ์
์ด๊ฒ์ด ์ ๊ฐ๋ฐ์๋ฅผ ๊ดด๋กญํ๊ฒ ํ๋๋ฉด, ์๋ฐ์ ์คํ ๋ฐ์ฑ & ์คํ ์ธ๋ฐ์ฑ ๊ณผ์ ์์ ์๋ฌ๋ผ๋ ๊น์ง ์ ๋ฌผ์ ๋ด์ด์ฃผ๊ธฐ ๋๋ฌธ์ด๋ค.
์๋์ผ๋ก ํ๋ณํ์ด ์งํ๋๋ ๋งํผ ํธ์ํจ์ ๊ฐ๋ฐ์์๊ฒ ์ ๊ณตํ์ง๋ง ๋์ ์ ๋ฒ๊ทธ๋ฅผ ์์์ฐจ๋ฆฌ๊ธฐ ์ด๋ ต๊ฒ ํ๋ค. ์๋ฅผ๋ค์ด Integer๋ Double๊ณผ ๊ฐ์ ๋ํผ(Wrapper) ํด๋์ค ๋ ํผ๋ฐ์ค๊ฐ null์ ์ฐธ์กฐํ๊ณ ์์ ๋, ์ด๋ฅผ ๊ธฐ๋ณธํ ํ์
์ผ๋ก ์ธ๋ฐ์ฑ(unboxing)ํ๋ ๋ก์ง์ด ์์ ๊ฒฝ์ฐ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
// Integer ๋ํผ๋ฐ์ค ํ์
์ ์ฌ์ฉํ๊ธฐ ์ํด ๋ณ์๋ฅผ ์ ์ธํ๊ณ 11 ๊ฐ์ผ๋ก ์ด๊ธฐํํ๋ค.
Integer BoxedValue = new Integer(11);
// ...
// ๋ง์ผ 1000์ค์ด ๋๋ ์ฝ๋์์ BoxedValue ๋ณ์๋ฅผ ๋ค๋ฃจ๋ค๊ฐ ์ด๋ ํ ์์ธ์ผ๋ก ์ธํด BoxedValue์ null ๊ฐ์ด ๋ค์ด๊ฐ๋ค๊ณ ๊ฐ์ ํ๋ค.
BoxedValue = null;
// Integer ๋ํผ ํ์
์ธ BoxedValue๋ฅผ int ํ์
์ผ๋ก ์๋ ํ๋ณํ ํ๋ ๊ณผ์ ์์ null์ primitive ํ์
์ ๋ฃ์์ ์์ด ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋ค
int intValue = boxedValue; // NullPointerException ๋ฐ์
์ด์ฒ๋ผ ์คํ ๋ฐ์ฑ(Auto-boxing)์ ๋์์ ๊ธฐ๋ํ๋ ์ํฉ์์ ๊ฐ๋ฐ์ ์๋์๋ ๋ค๋ฅด๊ฒ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ธฐ ์ฝ๋ค๋ ์ทจ์ฝ์ ์ด ์กด์ฌํ๋ค. ์ด๋ ์ปดํ์ผ ์์ ์์ ํ์ธํ ์ ์๊ณ ํ๋ก๊ทธ๋จ ์คํ ๊ณผ์ ์์ ๋ํ๋๋ ์๋ฌ์ด๊ธฐ ๋๋ฌธ์ ๊ต์ฅํ ์ฃผ์ํด์ผ ํ๋ค.
null ๊ณผ static ํค์๋
ํ๋ณํ ๋ฟ๋ง ์๋๋ผ null ์ ์ฐธ์กฐํ๋ ์ค๋ธ์ ํธ์ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ฒ ๋๋ฉด ์๋ฌ(NullPointerException)์ด ๋ฐ์ํ๋ค.
๊ทธ๋ฐ๋ฐ ๋ฉ์๋๊ฐ static์ผ๋ก ์ ์ธ๋์ด ์๋ ๊ฒฝ์ฐ๋ผ๋ฉด ์์ธ๊ฐ ๋ฐ์ํ์ง ์๊ณ ์ ์ ์คํ๋๋ค.
class Hello {
public void sayHello() {
System.out.println("hello object");
}
public static void sayHelloStatic() {
System.out.println("hello static");
}
}
Hello h = null; // Hello ๊ฐ์ฒด ๋ณ์์ null์ ์ฐธ์กฐ
h.sayHello(); // ERROR !!!
h.sayHelloStatic(); // ๋ ํผ๋ฐ์ค๊ฐ null์ด์ง๋ง ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์๋๋ค. (์คํ์ ๋๊ณ ๊ฒฝ๊ณ ๋ง ๋ฌ๋ค)
์๋ํ๋ฉด ํด๋์ค์ ์ ์ (static) ๋ฉค๋ฒ๋ ๊ฐ๊ฐ์ ์ธ์คํด์ค๊ฐ ์๋ ํด๋์ค์ ์ํ๊ธฐ ๋๋ฌธ์ ์ปดํ์ผ ํ์์ JVM์ static area์ ์ต์ ํ๊ฐ ๋๋ค. ๊ทธ๋์ ์ค๋ธ์ ํธ๊ฐ ์๋ ํด๋์ค๋ฅผ ํตํด ์ง๋ฐฉ์ผ๋ก ์ ์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ์ฝ๋๋ก ์๋ณ๋๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด ๋ณ์๊ฐ null์ด๋ ์๋๋ ๋ถ๋ฌ์ค๋๋ฐ๋ ๋ฌธ์ ๊ฐ ์๋ ๊ฒ์ด๋ค. (์ปดํ์ผ๋ฌ๋ ๋์ ์ ๊ฒฝ๊ณ ๋ฅผ ๋ด์ค๋ค)
๋ณดํต ์ ์ (static) ๋ฉ์๋๋ ์ฌ๋ฌ๋ถ๋ ์๋ค์ํผ ํด๋์ค๋ช
์ ํตํด ํธ์ถ Hello.sayHelloStatic() ํด์๋๋ฐ ์ด๋ฌํ ์ด์ ๊ฐ ์์ ํผ๋์ ์ค์ผ์ ์๊ธฐ ๋๋ฌธ์ ๊ทธ๋ ๊ฒ์ด๋ผ๊ณ ๋ด๋ ๋ฌด๋ฐฉํ๋ค.
null ๊ณผ instanceof ํค์๋
null์ ๋๋ค๋ฅธ ๋ ํนํ ํน์ง์ด null ์ ์ฐธ์กฐํ๋ ๋ ํผ๋ฐ์ค ๋ณ์์ instanceOf ์ฐ์ฐ์๋ฅผ ์ฌ์ฉํ๋ฉด false๋ฅผ ๋ฐํํ๋ค๋ ์ ์ด๋ค.
instanceOf ํค์๋๋ ์ฐธ์กฐ(reference) ๋ณ์๊ฐ ์ด๋ ๊ฐ์ฒด ํ์
์ธ์ง ๊ฒ์ฌ ํด์ฃผ๋ ์ฐ์ฐ์์ธ๋ฐ, ์๋ฌด๋ฆฌ null ์ด๋ผ ํด๋ ์ฒ์ ๋ณ์๋ฅผ ์ ์ธ ๋ฐ ์ด๊ธฐํ ํ ๋ String myReference = null ๋ก ์ง์ ๋ณ์์ ํ์
์ String์ผ๋ก ๋ช
์ ํด์คฌ์ ๋ถ๊ตฌํ๊ณ false๋ผ๊ณ ํ๋ ๋ฌด์ธ๊ฐ ์ด์ํ ์ง๋ ๋ชจ๋ฅธ๋ค. ๊ทธ๋ฌ๋ ์ ํํ๊ฒ ๋งํ๋ฉด instanceof ์ฐ์ฐ์๋ ์ฐธ์กฐ ๋ณ์์ ์ฃผ์๊ฐ์ ํ๊ณ ๊ฐ์ ํ ๋ฉ๋ชจ๋ฆฌ์ ์๋ ๊ฐ์ฒด์ ํ์
์ ๋ณด๊ณ ๋ฐํํ๊ธฐ ๋๋ฌธ์, ๊ฒฐ๊ตญ ์ฐธ์กฐํ๋ ์ฃผ์๊ฐ์ด ์๋ null ์ํ์ด๋ผ์ false๋ฅผ ๋ฐํํ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ง์ ๊ฐ์ ๋ค๋ฃจ๋ >, >=, <, <= ์ ๊ฐ์ด ํฌ๊ณ ์์์ ๋น๊ตํ๋ ๊ด๊ณ ์ฐ์ฐ์๋ฅผ null์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์๋ฌ(NullPointerException)์ด ๋ฐ์ํ๋ค. ๋ค๋ง ์์ธ๋ก ==, != ๊ณผ ๊ฐ์ ๊ด๊ณ ์ฐ์ฐ์๋ ์ฌ์ฉํ ์ ์๋ค.
public class Main {
public static void main(String[] args) {
String o = null;
if (o instanceof String) {
} else {
System.out.println("instanceof returned false"); // ์กฐ๊ฑด๋ฌธ์์ myReference๋ null์ด๊ธฐ ๋๋ฌธ์ false๋ฅผ ๋ฆฌํดํด์ ์ด์ชฝ์ด ์คํ๋๋ค
}
String o2 = "Hello World";
if (o2 instanceof String) {
System.out.println("myReference is a String"); // ์ถ๋ ฅ
}
}
}
NPE (NullPointerException)
์์์ ์ธ๊ธํ์๋ ์๋ฌ ๋ฉ์ธ์ง NullPointerException(์ดํ NPE)๋ null ์ฐธ์กฐ๋ก ์ธํด ์๋ฐ ๊ฐ๋ฐ์๋ค์ด ๊ฐ์ฅ ๊ณจ์น์ํ๊ฒ ๊ฒช๋ 1๋ฑ ๊ณต์ ์ด๋ค.
์์ ์ดํด๋ณธ ๊ฒ์ฒ๋ผ ์๋ฐ์์ null์ ์ฐธ์กฐ๊ฐ ์๋ ๊ฒฝ์ฐ๋ฅผ ๋ปํ๋๋ฐ, ๋ง์ผ null์ ์ฐธ์กฐํ๋ ๋ ํผ๋ฐ์ค ๋ณ์๋ก ๊ฐ์ฒด์ ์ธ์คํด์ค ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋ฑ์ ๊ฐ์ฒด ์ฝ๋๋ฅผ ์ํํ๋ ค๋ ๊ฒฝ์ฐ ์ด๋ NullPointerException๊ฐ ๋ฐ์ํ๋ค.
ํนํ๋ ๊ฐ๋ฐ์๋ฅผ ๊ณ ํต๋ฐ๊ฒ ํ๋ ์ด์ ๋ NullPointerException๊ฐ ํ๋ก๊ทธ๋จ ์คํ์ค์ธ ๋ฐํ์(Runtime) ์ํฉ์์ ๋ฐ์ํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ง์์ ์ปดํ์ผ ์์ ์์ ๋ฏธ๋ฆฌ ์์ ์์ผ๋ฉด ๋ฏธ๋ฆฌ๋ฏธ๋ฆฌ ์๋ฐฉํ ์ ์์ ํ ๋ฐ ๊ทธ๋ ์ง ์์ผ๋, ์๋ฐ ๊ฐ๋ฐ์์๊ฒ NPE๋ ์ฝ๋ ๋ฒ ์ด์ค ๊ณณ๊ณณ์ ๊น๋ ค์๋ ์ง๋ขฐ๊ฐ์ ๋ ์์ธ ๊ฒ์ด๋ค.
java.lang.NullPointerException
at seo.dale.java.practice(OptionalTest.java:26)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
NPE ๋ฐ์ ์๋๋ฆฌ์ค
๊ทธ๋ผ ์ ํํ ์๋ฐ ๊ฐ๋ฐ์๋ค์ด ์ฝ๋์์ ์ด๋ค ์ค์๋ฅผ ๋ฒํ๊ธฐ์ ์ง๋ขฐ๊ฐ ํ์ฒญ ํฐ์ง๋ ๊ฒ์ผ๊น?
๋ค์๊ณผ ๊ฐ์ด Person , Phone, OS ๋ผ๋ ํด๋์ค๊ฐ ์กด์ฌํ๋ค๊ณ ๊ฐ์ ํ์. ์ต์ข ๋ชฉํ๋ ๊ฐ ํด๋์ค์ ๋ฉ์๋ ์ฒด์ด๋์ ํตํด OS์ ์คํธ๋ง ๊ฐ์ ์ถ๋ ฅํ๋ ์์ ์ด๋ค.
class Person {
private Phone phone;
private String name; // ์์ฑ์์์ ์ด๊ธฐํ๋ฅผ ํจ
Person(String name) {
this.name = name;
}
public Phone getPhone() {
return this.phone;
}
}
class Phone {
private OS os; // ์์ฑ์์์ ์ด๊ธฐํ๋ฅผ ์ํจ
public OS getOS() {
return this.os;
}
}
class OS {
public String printOS() {
return "Android";
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("ํ๊ธธ๋");
p.getPhone().getOS().printOS(); // person์ Phone์ ์ป๊ณ ๊ทธ Phone์ OS๋ฅผ ์ป๊ณ OS๋ช
์ ์ถ๋ ฅํ๋ ํจ์ ์ฒด์ด๋
}
}
ํ์ง๋ง ์์ ์ฝ๋๋ฅผ ์คํํด๋ณด๋ฉด NPE(NullPointException)์ด ๋ฐ์ํ๊ฒ ๋๋ค. ์๋ํ๋ฉด p.getPhone().getOS().printOS() ์ฝ๋์์ p.getPhone() ์ ๋ฐํ๊ฐ์ด null ์ด๊ธฐ ๋๋ฌธ์ null.getOS() ๋ฉ์๋๊ฐ ์๋ํ์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
์ Phone ํ์
์ ๋ฉ์๋ getPhone() ์ด null์ ๋ฐํํ๋ ์ด์ ๋ฅผ ์ถ์ ํด๋ณด๋ฉด, new Person() ์ด ์ด๊ธฐํ๋ ๋ ์ธ์คํด์ค ๊ฐ์ฒด์ธ private Phone phone ์ ๊ฐ์ด ๋ค์ด๊ฐ์ง์์ null๋ก ๊ฐ์ด ๋ฐฐ์ ๋์๊ธฐ ๋๋ฌธ์ด๋ค. ๊ทธ๋ฆฌ๊ณ getPhone() ์์ Phone ํ์
์ ๊ฐ์ฒด this.phone์ ๋ฐํํ๋ฉด์ ์์ ๋ค์ด์๋ ๊ฐ์ธ null์ด ๊ทธ๋๋ก ๋์ด๊ฐ๊ฒ ๋๊ณ , null ๊ฐ์ฒด ์์ ์์ง๋ ์์ getOS() ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๋น์ฐํ NPE์๋ฌ๊ฐ ๋ฐ์๋ ๊ฒ์ด๋ค.
๋ณดํต ์์ ๊ฐ์ ๊ฒฝ์ฐ ์๋ฐ์คํฌ๋ฆฝํธ(JavaScript) ์ง์์์๋ ?. ์ฐ์ฐ์๋ก ๋งค์ฐ ๊ฐ๋จํ๊ฒ ํด๊ฒฐํ๋ค. (์ฝํ๋ฆฐ๋ ?: ์ ์ฌ์ฉํ๋ค)
// ๋ง์ฝ p๊ฐ null์ด ์๋๋ฉด getPhone() ์คํ
// ๋ง์ฝ getPhone() ์คํํ ๊ฒฐ๊ณผ ๋ฐํ๋ ๊ฐ์ด null์ด ์๋๊ฒฝ์ฐ getOS() ์คํ ...
p?.getPhone()?.getOS()?.printOS();
๊ทธ๋ฌ๋ ์๋ฐ(Java)์์๋ ์์ ๋ฌผ์ํ ์ฐ์ฐ์๋ฅผ ์ง์ํ์ง ์๋๋ค. ๋ฐ๋ผ์ ์ง์ ์กฐ๊ฑด๋ฌธ์ผ๋ก ํด๋น ๊ฐ์ฒด ๋ณ์๊ฐ null ์ธ์ง ์๋์ง ์ง์ ์กฐ๊ฑด์ ๋ฐ์ ธ์ NPE ๋ฌธ์ ๋ฅผ ํํผํด์ผ ํ๋ค.
์ฌ์ค null ์ฒ๋ฆฌ๋ฅผ ๊ฐ์ ํ๋ ค๋ ๋ ธ๋ ฅ์ ์๋ฐ7 ์์ ๋ถํฐ ์ธ๊ธ์ด ์์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์?.์ฐ์ฐ์์ ๊ฐ์ด ์๋น์ค ์ฐ์ฐ์(elvis operator)๊ฐ ์ ์๋์์ผ๋ ๊ฒฐ๊ณผ์ ์ผ๋ก๋ ์น์ธ๋์ง ์์๋ค.
NPE ๊ฐ๋ํ๋ ๊ณ ์ ์ ์ธ ๋ฐฉ๋ฒ
Java8 ์ด์ ์๋ ์ด๋ ๊ฒ NPE์ ์ํ์ ๋ ธ์ถ๋ ์ฝ๋๋ฅผ ๋ค์๊ณผ ๊ฐ์ ์กฐ๊ฑด๋ฌธ ์ค์ฒฉ ์ฝ๋ฉ ์คํ์ผ๋ก ํํผํ์๋ค.
Person p = new Person("ํ๊ธธ๋");
// p.getPhone().getOS().printOS();
Phone ph = p.getPhone();
if (ph != null) {
OS o = ph.getOS();
if(o != null) {
String n = o.printOS();
}
}
์ง๊ธ์ด์ผ ๋ฉ์๋ ๊ฐฏ์๊ฐ ๋ง์ง ์์ ๊ด์ฐฎ์ ๋ณด์ด์ง๋ง, ๋ง์ผ ๋ฉ์๋๊ฐ ๋ง์ผ๋ฉด ๋ง์ ์๋ก ์ผ์ผํ ๋ฐ์ ธ์ผ ํ๋ if๋ฌธ ์ญ์ ๊ธฐํ๊ธ์์ ์ผ๋ก ์ฆ๊ฐ๋์ด ์ฝ๋ ๊ฐ๋ ์ฑ์ด ๋งค์ฐ ์์ข์ ์ง ์๋ ์๋ค. ๊ทธ๋์ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ๋ ๊ฐ์ฒด ํจํด(Null Object Pattern) ์ด๋ผ๋ ๊ฐ์ฒด์งํฅ(oop)๋ฅผ ์์ฉํ ํจํด๋ ์์ง๋ง, ์ ์ง๋ณด์ ์ธก๋ฉด์์ ์คํ๋ ค ๋ ๋ณต์กํด์ง๋ ๋จ์ ์ด ์๊ธฐ ๋๋ฌธ์ ์ด ๋ฐฉ๋ฒ๋ ์ถ์ฒ๋์ด์ง์ง ์๋๋ค.
NPE ๊ฐ๋ํ๋ ์ต์ ๋ฐฉ๋ฒ (Optional ํด๋์ค)
์๋ฐ์ ํ์ ์ด๋ผ๊ณ ๋ถ๋ฆฌ์ฐ๋ Java8์ด ๋ฑ์ฅํ๋ฉด์ null์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ์ ์์ ์ผ๋ก ์ง์ํ๋ java.util.Optional ํด๋์ค๊ฐ ์ถ๊ฐ๋์๋ค. Optional ํด๋์ค๋ '์กด์ฌํ ์๋ ์์ง๋ง ์ ํ ์๋ ์๋ ๊ฐ์ฒด', ์ฆ, 'null์ด ๋ ์๋ ์๋ ๊ฐ์ฒด'์ ๊ฐ์ธ๊ณ ์๋ ์ผ์ข
์ ๋ํผ ํด๋์ค ์ด๋ค.
์ฝ๊ฒ ๋งํ๋ฉด ์ง์ ๋ค๋ฃจ๊ธฐ์ ๊น๋ค๋ก์ด null์ ๋ด์ ์ ์๋ ํน์ํ ๊ทธ๋ฆ ์ ๋๋ก ์๊ฐํ๋ฉด ๋๋ค. ๋ฐ๋ผ์ Optional ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ฉด ์์์น ๋ชปํ NullPointerException ์์ธ๋ฅผ ์ ๊ณต๋๋ ๋ฉ์๋๋ก ๊ฐ๋จํ ํํผํ ์ ์๊ฒ๋๋ค.
import java.util.Optional; // Optional ํด๋์ค ์ฌ์ฉํ๊ธฐ ์ํด import
class Person { ... }
class Phone { ... }
class OS { ... }
public class Main {
public static void main(String[] args) {
Person p = new Person("ํ๊ธธ๋");
Optional.ofNullable(p)
.map(Person::getPhone)
.map(Phone::getOS)
.map(OS::printOS);
}
}
# ์ฐธ๊ณ ์๋ฃ
https://gocoder.tistory.com/1856
https://madplay.github.io/post/what-is-null-in-java
https://www.daleseo.com/java8-optional-before/
https://programmerbay.com/how-to-make-an-object-eligible-for-garbage-collection-in-java/