2023. 3. 14. 09:52ใJAVA/Effective JAVA
[์ดํํฐ๋ธ ์๋ฐ] Item24. ๋ฉค๋ฒ ํด๋์ค๋ ๋๋๋ก static์ผ๋ก ๋ง๋ค๋ผ.
์ค์ฒฉ ํด๋์ค(nested class)๋ ๋ค๋ฅธ ํด๋์ค ์์ ์ ์๋ ํด๋์ค๋ฅผ ๋งํ๋ค.
์ค์ฒฉ ํด๋์ค๋ ์์ ์ ๊ฐ์ผ ๋ฐ๊นฅ ํด๋์ค์์๋ง ์ฐ์ฌ์ผ ํ๋ฉฐ, ๊ทธ ์ธ์ ์ฐ์์๊ฐ ์๋ค๋ฉด ํฑ๋ ๋ฒจ ํด๋์ค๋ก ๋ง๋ค์ด์ผ ํ๋ค.
์ค์ฒฉ ํด๋์ค์ ์ข ๋ฅ๋ ์ ์ ๋ฉค๋ฒ ํด๋์ค, ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค, ์ต๋ช ํด๋์ค, ์ง์ญ ํด๋์ค ๋ค๊ฐ์ง๊ฐ ์๋ค.
์ด ์ค ์ ์ ๋ฉค๋ฒ ํด๋์ค๋ฅผ ์ ์ธํ๋ฉด ๋๋จธ์ง๋ ๋ด๋ถ ํด๋์ค์ ํด๋นํ๋ค.
1๏ธโฃ ์ ์ ๋ฉค๋ฒ ํด๋์ค
: ์ ์ ๋ฉค๋ฒ ํด๋์ค๋ ๋ค๋ฅธ ํด๋์ค ์์ ์ ์ธ๋๊ณ , ๋ฐ๊นฅ ํด๋์ค์ private ๋ฉค๋ฒ์๋ ์ ๊ทผํ ์ ์๋ค๋ ์ ์ ์ ์ธํ๊ณ ๋ ์ผ๋ฐ ํด๋์ค์ ๋๊ฐ๋ค.
ex) ๊ณ์ฐ๊ธฐ๊ฐ ์ง์ํ๋ ์ฐ์ฐ ์ข ๋ฅ๋ฅผ ์ ์ํ๋ ์ด๊ฑฐํ์ ์ ์๊ฐํด๋ณด๋ฉด Operation ์ด๊ฑฐ ํ์ ์ Calculator ํด๋์ค์ public ์ ์ ๋ฉค๋ฒ ํด๋์ค๊ฐ ๋์ด์ผ ํ๋ค. ๊ทธ๋ฌ๋ฉด Calculator์ ํด๋ผ์ด์ธํธ์์ Calculator.Operation.PLUS ๋ Calculator.Operation.MINUS ์ ๊ฐ์ ํํ๋ก ์ฐ์ฐ์ ์ฐธ์กฐํ ์ ์๋ค.
public class OuterClass
{
private static int number = 10;
// static ๋ฉค๋ฒ ํด๋์ค
// static ํ๋์ ์ ๊ทผ ๊ฐ๋ฅ
// Outer class์ ์ธ์คํด์ค๋ฅผ ํ์๋ก ํ์ง ์๋๋ค. (static์ด๋ผ outer class์ ๋
๋ฆฝ์ )
static private class InnerClass {
void doSomething()
{
System.out.println("number = " + number);
}
}
public static void main(String[] args)
{
InnerClass innerClass = new InnerClass();
innerClass.doSomething();
}
}
2๏ธโฃ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค
๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค๋ ๋ฐ๊นฅ ํด๋์ค์ ์ธ์คํด์ค์ ์๋ฌต์ ์ผ๋ก ์ฐ๊ฒฐ๋๋ค.
๋ฐ๋ผ์ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค ๋ฉ์๋์์ ์ ๊ทํ๋ this๋ฅผ ์ฌ์ฉํด์ ๋ฐ๊นฅ ์ธ์คํด์ค์ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ฑฐ๋ ๋ฐ๊นฅ ์ธ์คํด์ค์ ์ฐธ์กฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค. (์ ๊ทํ๋ this๋ ํด๋์ค๋ช .this ํํ๋ก ๋ฐ๊นฅ ํด๋์ค์ ์ด๋ฆ์ ๋ช ์ํ๋ ์ฉ๋ฒ์ ๋งํ๋ค.)
๋ฐ๋ผ์ ๊ฐ๋ ์ฑ ์ค์ฒฉ ํด๋์ค์ ์ธ์คํด์ค๊ฐ ๋ฐ๊นฅ ์ธ์คํด์ค์ ๋ ๋ฆฝ์ ์ผ๋ก ์กด์ฌํ ์ ์๋ค๋ฉด ์ ์ ๋ฉค๋ฒ ํด๋์ค๋ก ๋ง๋ค์ด์ผ ํ๋ค.!!
(๋น์ ์ ๋ฉค๋ฒ ํด๋์ค๋ ๋ฐ๊นฅ ์ธ์คํด์ค ์์ด๋ ์์ฑํ ์ ์๊ธฐ ๋๋ฌธ)
public class OuterClass
{
private int number = 10;
void printNumber()
{
InnerClass innerClass = new InnerClass();
}
// ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค (static์ด ์๋ inner class)
// outer class์ ์ธ์คํด์ค์ ๋ํ ์ฐธ์กฐ๊ฐ ์๋ฌต์ ์ผ๋ก ์๊ธด๋ค. -> ์ฆ outer class ์์ด๋ inner class ์ฌ์ฉ x
private class InnerClass {
void doSomething()
{
System.out.println("number = " + number);
OuterClass.this.printNumber(); // outer class์ ๋ฉค๋ฒ์ ์ ๊ทผ ๊ฐ๋ฅ
}
}
public static void main(String[] args)
{
InnerClass innerClass = new OuterClass().new InnerClass();
innerClass.doSomething();
}
}
๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค์ ๋ฐ๊นฅ ์ธ์คํด์ค ์ฌ์ด์ ๊ด๊ณ๋ ๋ฉค๋ฒ ํด๋์ค๊ฐ ์ธ์คํด์คํ ๋ ๋ ํ๋ฆฝ๋๋ฉฐ ๋ ์ด์ ๋ณ๊ฒฝํ ์ ์๋ค.
์ด ๊ด๊ณ๋ ๋ฐ๊นฅ ํด๋์ค์ ์ธ์คํด์ค ๋ฉ์๋์์ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์์ฑ์๋ฅผ ํธ์ถํ ๋ ์๋์ผ๋ก ๋ง๋ค์ด์ง๋๊ฒ ๋ณดํต์ด์ง๋ง ๋๋ฌผ๊ฒ๋ ์ง์ ๋ฐ๊นฅ ์ธ์คํด์ค์ ํด๋์ค.new MemberClass(args)๋ฅผ ํธ์ถํด ์๋์ผ๋ก ๋ง๋ค๊ธฐ๋ ํ๋ค.
-> ์ด ๊ด๊ณ ์ ๋ณด๋ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค ์์ ๋ง๋ค์ด์ ธ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ฐจ์งํ๋ฉฐ, ์์ฑ ์๊ฐ๋ ๋ ๊ฑธ๋ฆฐ๋ค.
public class MySet<E> extends AbstractSet<E>
{
@Override
public Iterator<E> iterator()
{
return new MyIterator();
}
@Override
public int size()
{
return 0;
}
private class MyIterator implements Iterator<E>
{
@Override
public boolean hasNext()
{
return false;
}
@Override
public E next()
{
return null;
}
}
}
๋น์ ์ ๋ฉค๋ฒ ํด๋์ค๋ ์ด๋ํฐ๋ฅผ ์ ์ํ ๋ ์์ฃผ ์ฌ์ฉํ๋ค.
์ด๋ค ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ๊ฐ์ธ ๋ง์น ๋ค๋ฅธ ํด๋์ค์ ์ธ์คํด์ค์ฒ๋ผ ๋ณด์ด๊ฒ ํ๋ ๋ทฐ๋ก ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
Set, List์ ๊ฐ์ ๋ค๋ฅธ ์ปฌ๋ ์ ์ธํฐํ์ด์ค ๊ตฌํ๋ค๋ ์์ ์ ๋ฐ๋ณต์๋ฅผ ๊ตฌํํ ๋ ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค๋ฅผ ์ฃผ๋ก ์ฌ์ฉํ๋ค.
๋ฉค๋ฒ ํด๋์ค์์ ๋ฐ๊นฅ ์ธ์คํด์ค์ ์ ๊ทผํ ์ผ์ด ์๋ค๋ฉด ๋ฌด์กฐ๊ฑด static์ ๋ถ์ฌ์ ์ ์ ๋ฉค๋ฒ ํด๋์ค๋ก ๋ง๋ค์!!
static์ ์๋ตํ๋ฉด ๋ฐ๊นฅ ์ธ์คํด์ค๋ก์ ์จ์ ์ธ๋ถ ์ฐธ์กฐ๋ฅผ ๊ฐ๊ฒ ๋๋ค. ์ด ์ฐธ์กฐ๋ฅผ ์ ์ฅํ๋ ค๋ฉด ์๊ฐ๊ณผ ๊ณต๊ฐ์ด ์๋น๋๊ณ , ๋ ์ฌ๊ฐํ ๋ฌธ์ ๋ก๋ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ด ๋ฐ๊นฅ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์๊ฑฐํ์ง ๋ชปํ๋ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ์๊ธธ ์ ์๋ค๋ ์ ์ด๋ค.
์ฐธ์กฐ๊ฐ ๋์ ๋ณด์ด์ง ์๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ์ ์์ธ์ ์ฐพ๊ธฐ ์ด๋ ค์ ๋๋๋ก ์ฌ๊ฐํ ์ํฉ์ ์ด๋ํ๊ธฐ๋ ํ๋ค.
3๏ธโฃ ์ต๋ช ํด๋์ค
: ๋ฐ๊นฅ ํด๋์ค์ ๋ฉค๋ฒ๊ฐ ์๋, ์ฐ์ด๋ ์์ ์ ์ ์ธ๊ณผ ๋์์ ์ธ์คํด์ค๊ฐ ๋ง๋ค์ด์ง๋ค. ๋ฐ๋ผ์ ์ฝ๋์ ์ด๋์๋ ๋ง๋ค ์ ์๋ค.
์ต๋ช ํด๋์ค๋ ๋น์ ์ ์ธ ๋ฌธ๋งฅ์์ ์ฌ์ฉ๋ ๋๋ง ๋ฐ๊นฅ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ ์ ์๋ค. ์ ์ ๋ฌธ๋งฅ์์๋ผ๋ ์์ ๋ณ์ ์ด์ธ์ ์ ์ ๋ฉค๋ฒ๋ ๊ฐ์ง ์ ์๋ค.
์ต๋ช ํด๋์ค๋ ์ ์ธํ ์ง์ ์์๋ง ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๊ณ , instanceof ๊ฒ์ฌ๋ ํด๋์ค์ ์ด๋ฆ์ด ํ์ํ ์์ ์ ์ํํ ์ ์๋ค.
์๋ฐ์์ ์ต๋ช ํด๋์ค๋ ๋๋ค๋ฅผ ์ง์ํ๊ธฐ ์ ์ ์ฆ์์์ ์์ ํจ์ ๊ฐ์ฒด๋ ์ฒ๋ฆฌ ๊ฐ์ฒด๋ฅผ ๋ง๋ค ๋ ์ฌ์ฉํ๋ค.
์ต๋ช ํด๋์ค์ ๋ ๋ค๋ฅธ ์ฃผ ์ฐ์์ ์ ์ ํฉํฐ๋ฆฌ ๋ฉ์๋๋ฅผ ๋ง๋ค ๋ ์ฌ์ฉํ ์ ์๋ค.
public class IntArrays
{
static List<Integer> intArrayAsList(int[] a)
{
Objects.requireNonNull(a);
return new AbstractList<>()
{
@Override
public Integer get(int index)
{
return a[index];
}
@Override
public Integer set(int index, Integer element)
{
int oldVal = a[index];
a[index] = element;
return oldVal;
}
@Override
public int size()
{
return a.length;
}
};
}
public static void main(String[] args)
{
int[] a = new int[10];
for (int i = 0; i < a.length; i++)
{
a[i] = i;
}
}
}
4๏ธโฃ ์ง์ญ ํด๋์ค
: ์ง์ญ ํด๋์ค๋ ๋ค๊ฐ์ง ์ค์ฒฉ ํด๋์ค ์ค ๊ฐ์ฅ ๋๋ฌผ๊ฒ ์ฌ์ฉ๋๋ค.
์ง์ญ ํด๋์ค๋ ์ง์ญ ๋ณ์๋ฅผ ์ ์ธํ ์ ์๋ ๊ณณ์ด๋ผ๋ฉด ์ค์ง์ ์ผ๋ก ์ด๋๋ ์ ์ธํ ์ ์๊ณ , ์ ํจ ๋ฒ์๋ ์ง์ญ๋ณ์์ ๊ฐ๋ค.
public class MyClass
{
private int number = 10;
void doSomething()
{
// ๋ฉค๋ฒ ํด๋์ค๊ฐ ์๋ local class -> ๊ฑฐ์ ์ฌ์ฉ x
class LocalClass {
private void printNumber()
{
System.out.println("number = " + number);
}
}
LocalClass localClass = new LocalClass();
localClass.printNumber();
}
public static void main(String[] args)
{
MyClass myClass = new MyClass();
myClass.doSomething();
}
}
์ต๋ช ํด๋์ค๋ ๋น์ ์ ๋ฌธ๋งฅ์์ ์ฌ์ฉ๋ ๋๋ง ๋ฐ๊นฅ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ ์ ์์ผ๋ฉฐ, ์ ์ ๋ฉค๋ฒ๋ ๊ฐ์ง ์ ์์ผ๋ฉฐ, ๊ฐ๋ ์ฑ์ ์ํด ์งง๊ฒ ์์ฑํด์ผ ํ๋ค.
๐ ์ ๋ฆฌ
์ค์ฒฉ ํด๋์ค์๋ ๋ค๊ฐ์ง, ์ ์ ๋ฉค๋ฒ ํด๋์ค, ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค, ์ต๋ช ํด๋์ค, ์ง์ญ ํด๋์ค๊ฐ ์๊ณ ๊ฐ๊ฐ์ ์ฐ์์ด ๋ค๋ฅด๋ค.
๋ฉ์๋ ๋ฐ์์๋ ์ฌ์ฉํด์ผ ํ๊ณ , ๋ฉ์๋ ์์ ์ ์ํ๊ธฐ์๋ ๋๋ฌด ๊ธธ๋ค๋ฉด ๋ฉค๋ฒ ํด๋์ค๋ก ๋ง๋ ๋ค.
๋ฉค๋ฒ ํด๋์ค์ ์ธ์คํด์ค๊ฐ ๊ฐ๊ฐ ๋ฐ๊นฅ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๋ค๋ฉด ๋น์ ์ ๋ฉค๋ฒ ํด๋์ค๋ก, ๊ทธ๋ ์ง ์๋ค๋ฉด ์ ์ ์ผ๋ก ๋ง๋ค์!!
์ค์ฒฉ ํด๋์ค๊ฐ ํ ๋ฉ์๋ ์์์๋ง ์ฐ์ด๋ฉด์ ๊ทธ ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ ์ง์ ์ด ๋จ ํ ๊ณณ์ด๊ณ ํด๋น ํ์ ์ผ๋ก ์ฐ๊ธฐ์ ์ ํฉํ ํด๋์ค๋ ์ธํฐํ์ด์ค๊ฐ ์ด๋ฏธ ์๋ค๋ฉด ์ต๋ช ํด๋์ค๋ก ๋ง๋ค๊ณ ์๋๋ฉด ์ง์ญ ํด๋์ค๋ก ๋ง๋ค์!!