Post

[TIL] 계산기 프로젝트를 하며 배운 지식 3가지

[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문을 여러번 작성할 수 있습니다
  • 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) 등등이 있습니다

This post is licensed under CC BY 4.0 by the author.