✔️ 프로세스 구조
1. Code 영역 : Java main 메소드와 같은 코드 의미
2. Data 영역 : 전역변수, 정적변수, 배열 등 초기화 된 데이터를 저장
3. Memory 영역
자바에서 쓰레드를 구현하고 실행하는 방법에는 여러가지가 있다.
1. Thread Class 이용
public class TestThread extends Thread {
@Override
public void run() {
// 쓰레드 수행작업
}
}
TestThread thread = new TestThread(); // 쓰레드 생성
thread.start() // 쓰레드 실행
2. Runnable 인터페이스 이용
Runable은 인터페이스이기 때문에 클래스인 Thread를 상속받아 처리하는 것에 비해 확장성이 좋다. 다른 필요한 클래스를 더 상속받을 수 있디 때문이다.
public class TestRunnable implements Runnable {
@Override
public void run() {
// 쓰레드 수행작업
}
}
Runnable run = new TestRunnable();
Thread thread = new Thread(run); // 쓰레드 생성
thread.start(); // 쓰레드 실행
extends
키워드를 이용해 타입 매개변수를 특정 타입으로 제한할 수 있다.
다음과 같이 <T extends Animal>
이라고 해두면, Animal
과 그 자식들만 받을 수 있도록 제한을 둘 수 있다. 즉 T
의 상한이 Animal
이 된다. 기존에 그냥 <T>
만 해두었을 때는 Animal
타입뿐만 아니라 전혀 상관없는 Integer
나 String
타입도 들어올 수 있었다. 하지만 이렇게 타입 매개변수를 제한하면 이런 문제를 해결할 수 있다.
public class AnimalHospitalV3<T extends Animal> {
// Animal이나 Animal의 자식들만 올 수 있음!(Object도 못옴)
private T animal;
public void set(T animal) {
this.animal = animal;
}
public void checkup() {
System.out.println("동물 이름: " + animal.getName());
System.out.println("동물 크기: " + animal.getSize());
animal.sound();
}
public T bigger(T target) {
return animal.getSize() > target.getSize() ? animal : target;
}
}
✔️ 제네릭 메서드?
다음과 같이 제네릭 타입으로 클래스를 정의하지 않고도 제네릭 메서드를 활용해 원하는 기능을 구현할 수도 있다.
public class AnimalMethod {
public static <T extends Animal> void checkup(T t) {
System.out.println("동물 이름: " + t.getName());
System.out.println("동물 크기: " + t.getSize());
t.sound();
}
public static <T extends Animal> T bigger(T t1, T t2) {
return t1.getSize() > t2.getSize() ? t1 : t2;
}
}
다음과 같이 사용할 수 있다. 제네릭 메서드를 호출할 때 타입 추론을 사용하므로 <Dog>
과 같이 따로 적어주지 않아도 된다.
public class MethodMain2 {
public static void main(String[] args) {
Dog dog = new Dog("멍멍이", 100);
Cat cat = new Cat("야옹이", 100);
AnimalMethod.checkup(dog);
AnimalMethod.checkup(cat);
Dog targetDog = new Dog("큰 멍멍이", 200);
Dog bigger = AnimalMethod.bigger(dog, targetDog);
System.out.println("bigger = " + bigger);
}
}
또한, 제네릭 타입보다 제네릭 메서드가 높은 우선순위를 가지므로 제네릭 타입과 제네릭 메서드의 타입 매개변수를 같은 이름으로 사용하면 제네릭 메서드가 먼저 적용된다. 하지만 애초에 이름을 다른 이름으로 하는 것이 더 좋다.
제네릭을 배우고 직접 사용해본 적은 처음이어서 이게 맞는지 고민했다.
public T calculate(T num1, T num2, char operator) {
double result = 0;
switch (operator) {
case '+':
result = ADD.apply((Double) num1, (Double) num2);
break;
case '-':
result = SUBTRACT.apply((Double) num1, (Double) num2);
break;
case '*':
result = MULTIPLY.apply((Double) num1, (Double) num2);
break;
case '/':
result = DIVIDE.apply((Double) num1, (Double) num2);
break;
default:
System.out.println("올바른 연산자를 입력하세요.");
}
if (num1 instanceof Integer && num2 instanceof Integer) {
T castedResult = (T) Integer.valueOf((int) result);
results.add(castedResult);
return castedResult;
} else {
T castedResult = (T) Double.valueOf(result);
results.add(castedResult);
return castedResult;
}
}
조금 여유롭다고 생각했던 계산기 과제..리드미랑 트러블 슈팅 정리도 아직 못했는데 벌써 내일 제출이다. 내일은 조금 일찍 시작해 점심 먹기 전에 과제를 내고 싶다.😂