[TIL] 계산기 프로젝트를 하며 배운 지식 3가지
TIL = Today I Learn, 직역하면 ‘내가 배운 것’을 정리하는 의미입니다
TIL을 작성해야 할 일이 점차 생기는 것 같으니 TIL 카테고리를 만들게 되었습니다
앞으로는 TIL 카테고리에 새롭게 배운 내용이나 마주했던 문제를 해결하는 방법에 대해 작성해보도록 하겠습니다
이번 TIL에서는 각 단계별을 진행하며 새로 배운 내용을 정리해보았습니다
첫 개인 프로젝트, 계산기 (Calculator)
링크 - 계산기 프로젝트 Repository
일주일의 개발 기간동안 JAVA 강의를 들으면서 프로젝트를 진행하였습니다
이 프로젝트를 통해 객체와 인스턴스, 스트림, 제네릭 등 다양한 기술을 적용해보았습니다
덤으로 브랜치를 나누어 개발하며 Git Merge를 하는 방법도 사용해보았구요
계산기 1단계 - try-catch-finally
IntelliJ를 설치하고 JVM, JDK 버전과 프로젝트 설정을 마친 뒤, 새로운 클래스를 만들어 간단한 계산기를 만들면 됩니다
다만, 예외 처리를 제대로 사용해보는 것은 이번이 처음이었기에 이 내용을 자주 찾아보게 되었습니다
1
2
3
4
5
6
7
8
9
10
11
12
// int num1 = 10;
// int num2 = 0;
try {
// 예외가 발생할 수 있는 코드 작성
int result = num1/num2;
System.out.println("num1 / num2 = " + result);
} catch (ArithmeticException e) {
System.out.println("0으로 나눌 수 없습니다.");
} finally {
System.out.println("프로그램을 종료합니다.");
}
Java-Basic
카테고리에 아직 작성하지 않은 try-catch-finally
문법입니다
- try
- 예외가 발생할 수 있는 코드를 작성합니다
- 만약
try-catch
를 작성하지 않은 채 위 예시처럼 0으로 나눌 경우 오류가 발생하게 됩니다 - try 문 안에 오류가 발생할 경우, try 문 코드 실행을 중지하고 catch 문으로 전달됩니다
- catch
- try 문에서 전달받은 경우, 0으로 나누면 생기는 예외인
ArithmeticException
을 전달받으며 실행됩니다 - 예외 종류가 다양하기 떄문에 찾아보거나 코드를 실행하면서 출력되는 에러 발생 로그를 작성하면 됩니다
- 에러 종류가 다양할 경우
Exception
를 작성하여 처리할 수 있습니다- (ArithmeticException은 RuntimeException을, RuntimeException은 Exception을 상속하고 있습니다)
- catch문을 여러번 작성할 수 있습니다
- try 문에서 전달받은 경우, 0으로 나누면 생기는 예외인
- finally
- 예외처리가 발생함의 여부에 상관없이 작동합니다
계산기 2단계 - switch expression
1단계는 App
클래스에서 모두 동작하도록 코드를 작성하였으나 2단계는 계산을 처리해주는 클래스를 만들어야 합니다
- Getter과 Setter를 통해 private 변수를 접근 및 조회할 수 있도록 설정하
- switch 문을 통해 입력받은 연산 기호에 따라 계산 수행
- List 타입의
Results
에 계산 결과들을 기록- 마지막으로 기록된 값을 지울 수 있도록 설정
2단계에서는 Java 12부터 추가된 새로운 switch expression
을 사용하였습니다
1
2
3
4
5
6
7
8
String str = "A0";
int value = switch (str) {
case "A0", "A1" -> 10;
case "B0" -> 20;
case "B1" -> 21;
default -> -1;
};
이제는 값을 리턴받을 수 있으며, 람다식으로 값을 받으면 switch 문이 종료되기에 break
를 작성할 필요가 없습니다
게다가 예시처럼 같은 값을 리턴하는 case를 여러번 적을 필요 없이 “,”로 구분지어 한 줄에 작성할 수 있습니다
단, 값을 리턴받는 switch 문을 작성할 경우
default
를 반드시 정의해야 합니다
계산기 3단계 - Generic
3단계는 기본적인 내용으로 작성하던 1 ~ 2단계와 다르게
이넘, 람다, 스트림, 제네릭 등을 사용해야되기 때문에 난이도가 조금 더 높은 편입니다
여기서 제네릭 타입을 새로 알게 되었으니 한 번 알아보도록 하겠습니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class MyClass<T extends Number> {
public void print(T num) {
System.out.println("print number : " + num);
}
}
public class Main {
public static void main(String[] args) {
MyClass<Integer> myClass = new MyClass<>();
myClass.print(10);
}
}
클래스 뒤에 <T extends Number>
을 작성하였으며
Main에서 MyClass 객체를 만들 때 <Integer>
을 붙여 타입이 Integer
로 지정된 것을 볼 수 있습니다
이렇게 작성을 할 경우, 의도와 다르게 잘못된 타입을 사용하는 것을 방지할 수 있습니다
그리고 외부에서 타입을 지정해주기 때문에 String
, Double
으로 사용하는 등 클래스의 재사용성이 높아집니다
Generic의 특징
Reference Type만 사용 가능
아마 List를 사용해본 적이 있다면Integer
,Double
을 써야한다는 것에 의문을 품어보았을겁니다
int, double과 같은 원시 타입(Primitive Type)은 이전 버전의 JVM과의 하위 호환성을 위해서입니다Generic의 불공변성
만약MyClass<Integer>
를 작성하였다면MyClass<Double>
처럼 다른 타입으로 변환할 수 없습니다
하지만 이런 특징으로 인해 문제점이 생기는 경우 다른 방법으로 응용하는 것을 찾아봐야 합니다타입 기호 네이밍
꼭 “T”를 작성해야 하는 것은 아니지만 일반적으로 약속된 네이밍을 사용할 것을 권장합니다
Type(T), Element(E), Key(K) 등등이 있습니다