public class LocalOuterV1 {
private int outInstanceVar = 3;
public void process(int paramVar) {
int localVar = 1;
class LocalPrinter {
int value = 0;
public void print() {
System.out.println("value=" + value);
System.out.println("localVar=" + localVar);
System.out.println("paramVar=" + paramVar);
System.out.println("outInstanceVar=" + outInstanceVar);
}
}
LocalPrinter localPrinter = new LocalPrinter();
localPrinter.print();
}
public static void main(String[] args) {
LocalOuterV1 localOuterV1 = new LocalOuterV1();
localOuterV1.process(2);
}
}
value
에 접근 가능localVar
에 접근 가능paramVar
에 접근 가능outInstanceValue
에 접근 가능✔️지역 클래스 인터페이스 구현
public interface Printer {
void print();
}
public class LocalOuterV2 {
private int outInstanceVar = 3;
public void process(int paramVar) {
int localVar = 1;
class LocalPrinter implements Printer {
int value = 0;
@Override
public void print() {
System.out.println("value=" + value);
System.out.println("localVar=" + localVar);
System.out.println("paramVar=" + paramVar);
System.out.println("outInstanceVar=" + outInstanceVar);
}
}
LocalPrinter localPrinter = new LocalPrinter();
localPrinter.print();
}
public static void main(String[] args) {
LocalOuterV2 localOuterV1 = new LocalOuterV2();
localOuterV1.process(2);
}
}
public class LocalOuterV3 {
private int outInstanceVar = 3;
public Printer process(int paramVar) {
int localVar = 1;
// 지역 클래스
class LocalPrinter implements Printer {
int value = 0;
@Override
public void print() {
System.out.println("value = " + value);
System.out.println("localVar = " + localVar);
System.out.println("paramVar = " + paramVar);
System.out.println("outInstanceVar = " + outInstanceVar);
}
}
LocalPrinter localPrinter = new LocalPrinter();
// localVar = 2;
// paramVar = 100;
return localPrinter;
}
public static void main(String[] args) {
LocalOuterV3 localOuterV3 = new LocalOuterV3();
Printer printer = localOuterV3.process(2);
printer.print();
}
}
❗지역 클래스가 접근하는 지역 변수는 절대로 중간에 값이 변하면 안 된다.
effectively final이라 한다. 사실상 final 지역 변수는 지역 변수에 final 키워드를 사용하지 않았지만, 값을 변경하지 않는 지역 변수를 뜻한다. final 키워드를 넣지 않았을 뿐이지 실제로 final 키워드를 넣은 것처럼 중간에 값을 변경하지 않는 지역 변수이다.
익명 클래스는 지역 클래스의 특별한 종류 중 하나로 클래스의 이름이 없다는 것이 특징이다.
public class AnonymousOuter {
private int outInstanceVar = 3;
public void process(int paramVar) {
int localVar = 1;
// 익명 클래스의 선언과 생성
// new 다음에 상속받으면서 구현할 부모 타입을 입력
// Printer를 생성하는 것 X → Printer라는 이름의 인터페이스를 구현한 익명 클래스 생성
Printer printer = new Printer() {
int value = 0;
@Override
public void print() {
System.out.println("value=" + value);
System.out.println("localVar=" + localVar);
System.out.println("paramVar=" + paramVar);
System.out.println("outInstanceVar=" + outInstanceVar);
}
};
printer.print();
System.out.println("printer.class : " + printer.getClass());
}
public static void main(String[] args) {
AnonymousOuter anonymousOuter = new AnonymousOuter();
anonymousOuter.process(2);
}
}
❗문제1 : Ex0Main 코드를 리팩토링
public class Ex0Main {
public static void helloJava() {
System.out.println("프로그램 시작");
System.out.println("Hello Java");
System.out.println("프로그램 종료");
}
public static void helloSpring() {
System.out.println("프로그램 시작");
System.out.println("Hello Spring");
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
helloJava();
helloSpring();
}
}
❗해결1 : Ex0RefMain → 코드의 중복이 보인다. 이 부분을 리팩토링하면서 또한 전달하려는 문자열을 파라미터로 넘기면 되겠다.
public class Ex0RefMain {
public static void hello(String str) {
System.out.println("프로그램 시작");
System.out.println("Hello " + str);
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
hello("Java");
hello("Spring");
}
}
❗문제2 : Ex1Main 코드를 리팩토링
public class Ex1Main {
public static void helloDice() {
System.out.println("프로그램 시작");
//코드 조각 시작
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
//코드 조각 종료
System.out.println("프로그램 종료");
}
public static void helloSum() {
System.out.println("프로그램 시작");
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
helloDice();
helloSum();
}
}
❗해결1 : Ex1RefMain1 → 정적 중첩 클래스 활용
public class Ex1RefMain1 {
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
System.out.println("프로그램 종료");
}
static class Dice implements Process {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
}
}
static class Sum implements Process {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
}
}
public static void main(String[] args) {
Process dice = new Dice();
Process sum = new Sum();
hello(dice);
hello(sum);
}
}
❗해결2 : Ex1RefMain2 → 지역 클래스 사용
public class Ex1RefMain2 {
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
class Dice implements Process {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
}
}
class Sum implements Process {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
}
}
Process hello = new Dice();
Process sum = new Sum();
hello.run();
sum.run();
}
}
❗해결3 : Ex1RefMain3 → 익명 클래스 사용
public class Ex1RefMain3 {
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
Process sum = new Process() {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
}
};
Process dice = new Process() {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
}
};
hello(sum);
hello(dice);
}
}
❗해결4 : Ex1RefMain4 → 익명 클래스 사용(참조값을 직접 전달)
public class Ex1RefMain4 {
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
hello(new Process() {
@Override
public void run() {
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
}
});
hello(new Process() {
@Override
public void run() {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
}
});
}
}
❗해결5 : Ex1RefMain5 → 참조값을 직접 전달하는 방식 → 람다
public class Ex1RefMain5 {
public static void hello(Process process) {
System.out.println("프로그램 시작");
process.run();
System.out.println("프로그램 종료");
}
public static void main(String[] args) {
hello(() -> {
for (int i = 1; i <= 3; i++) {
System.out.println("i = " + i);
}
});
hello(() -> {
int randomValue = new Random().nextInt(6) + 1;
System.out.println("주사위 = " + randomValue);
});
}
}