2024. 12. 31. 20:44ㆍ개발 회고/TIL
😊오늘 배운 내용
자바문법 1주차 완강
git 협업 시 branch 관리
[어떤 문제가 있었는지 + 어떻게 해결하였는지]
1. Scanner로 입력 받을 시 줄바꿈문제
자바문법 1주차 숙제에서 다음과 같은 문제가 있었다.
요리 레시피 메모장 만들기
입력값
내가 좋아하는 요리 제목을 먼저 입력합니다.
요리 별점을 1~5 사이의 소수점이 있는 실수로 입력해 주세요. (ex. 3.5)
이어서 내가 좋아하는 요리 레시피를 한 문장씩 10문장을 입력합니다.
출력값
입력이 종료되면 요리 제목을 괄호로 감싸서 먼저 출력해 줍니다.
이어서, 요리 별점을 소수점을 제외한 정수로만 출력해 줍니다. (ex. 3)
바로 뒤에 정수 별점을 5점 만점 퍼센트로 표현했을 때 값을 실수로 출력해 줍니다. (ex. 60.0%)
이어서, 입력한 모든 문장 앞에 번호를 붙여서 모두 출력해 줍니다.
다음은 내가 처음에 작성한 코드이다.
import java.util.Scanner;
public class recipe {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String title = sc.nextLine();
double star = sc.nextDouble();
double percent = (star/5)*100;
String space = sc.nextLine();
String recipe1 = sc.nextLine();
String recipe2 = sc.nextLine();
String recipe3 = sc.nextLine();
String recipe4 = sc.nextLine();
String recipe5 = sc.nextLine();
String recipe6 = sc.nextLine();
String recipe7 = sc.nextLine();
String recipe8 = sc.nextLine();
String recipe9 = sc.nextLine();
String recipe10 = sc.nextLine();
System.out.println("["+ title + "]");
System.out.println(star + " ("+ percent + "%)");
System.out.println("1. "+recipe1);
System.out.println("2. "+recipe2);
System.out.println("3. "+recipe3);
System.out.println("4. "+recipe4);
System.out.println("5. "+recipe5);
System.out.println("6. "+recipe6);
System.out.println("7. "+recipe7);
System.out.println("8. "+recipe8);
System.out.println("9. "+recipe9);
System.out.println("10. "+recipe10);
}
}
반복문도 적용안하고 무식하게 짠 코드이다.
문제는 별점을 입력받고 나서 그 다음 레시피 내용을 입력받을 때이다. 사용자가 별점을 입력 후에 엔터를 치게 되버리면 그 다음 줄 문자를 읽을 때 줄바꿈 문자를 읽게 되어버려서 레시피 내용을 입력받을 수 없게 되는 문제가 생겼다.
Scanner로 입력받으면 입력버퍼라는 것이 생기게 된다.
입력 버퍼는 사용자가 입력한 데이터가 임시로 저장되는 공간이다. Scanner 객체는 이 버퍼에서 데이터를 읽어오며, 메서드(nextInt(), nextLine(), 등)를 호출할 때마다 버퍼에 남아 있는 데이터를 처리한다.
문제상황
Scanner sc = new Scanner(System.in);
int number = sc.nextInt(); // 정수를 입력받음 (예: 5 입력)
String text = sc.nextLine(); // 문자열을 입력받음 (예: "Hello")
System.out.println("number: " + number);
System.out.println("text: " + text);
위 코드를 실행하면:
- sc.nextInt()는 정수만 읽는다. (예: 5)
- 사용자가 Enter를 입력하면, 개행 문자(\n)가 입력 버퍼에 남게 된다.
- sc.nextLine()은 입력 버퍼에 남아 있던 \n을 읽어버리기 때문에, 사용자가 입력을 하지 않았더라도 빈 문자열("")을 반환한다.
따라서 다음과 같이 nextLine()을 이용해 버퍼를 비워주는 작업을 해야한다.
sc.nextLine(); // 입력 버퍼에 남아 있는 개행 문자를 제거
2. 동적배열 ArrayList<>
위에 짰던 코드의 효율을 더 개선하고 클린코드로 작성하기 위해 다음과 같이 코드를 작성했다.
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Scanner;
public class recipe_clean {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("레시피의 제목을 입력하세요 ");
String title = sc.nextLine();
System.out.println("레시피의 별점을 입력하세요 ");
double star = sc.nextDouble();
double percent = (star/5)*100;
sc.nextLine(); //버퍼비우기
System.out.println("레시피의 내용을 입력하세요");
ArrayList<String> recipeArray = new ArrayList<>();
while (true) {
String recipe = sc.nextLine();
if (recipe.isEmpty()) {
break;
}
recipeArray.add(recipe);
}
System.out.println("[" + title + "]");
System.out.println(star + " (" + percent + "%)");
for(int i = 0; i < recipeArray.size(); i++) {
System.out.println((i+1)+". " + recipeArray.get(i));
}
}
}
이 코드에선 ArrayList<>와 for문,While문이 등장한다.
먼저 ArrayList란 Java의 java.util 패키지에 포함된 동적 배열 클래스이다.
동적배열이란?
일반적인 배열(String[])과는 달리, 크기를 미리 정하지 않아도 필요에 따라 크기를 자동으로 확장하거나 줄일 수 있는 배열을 말한다.
ArrayList<>의 <>는 제네릭(Generic) 타입을 지정하는 부분이다.
이는 ArrayList에 저장될 데이터 타입이 String임을 명시하는 뜻이다. 즉, 이 ArrayList에는 String 타입 데이터만 저장할 수 있다.
new ArrayList<>() 는 new 연산자를 이용해 ArrayList 객체를 생성하는 부분이다.
그렇다면 자바에서 클래스나 객체, 자료구조를 생성할 때 항상 new 연산자를 사용해야 하는 것인가?
결론은 아니다. 사용할 때도 있고 생략할 때도 있다.
일반적인 정적배열을 살펴보면,
//new 사용
int[] numbers = new int[5]; // 길이가 5인 정수 배열 생성
numbers[0] = 10; // 배열의 첫 번째 요소에 값 할당
//new 생략
int[] numbers = {10, 20, 30, 40, 50}; // 배열 선언 및 초기화
그러나 컬렉션 자료구조를 사용할 때는 무조건 new 생성자를 이용해야 한다.
이는 컬렉션이 배열과 달리 동적 자료구조이며, 자바의 java.util 패키지에 정의된 클래스이기 때문이다.
import java.util.ArrayList;
public class Example {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>(); // new로 생성
list.add("Apple");
list.add("Banana");
System.out.println(list); // 출력: [Apple, Banana]
}
}
컬렉션 클래스는 단순히 선언만으로는 사용할 수 없다. 반드시 new를 통해 객체를 생성해야 데이터를 추가하거나 사용할 수 있다.
| 배열 (Array) | 생략 가능 ({} 사용 시) | 선언과 동시에 값을 초기화할 때 new 생략 가능. |
| ArrayList | 반드시 필요 | 컬렉션은 동적 자료구조이므로 항상 new로 객체를 생성해야 함. |
| HashMap | 반드시 필요 | 컬렉션 클래스는 반드시 객체 생성이 필요. |
| Primitive 변수 | 필요 없음 | int, char 같은 원시 타입 변수는 바로 선언 가능. |
| 클래스 객체 | 반드시 필요 | 클래스 객체 생성 시 반드시 new 사용 (String 제외). |
3. 문자 vs 문자열
기존에 계속 쓰던 파이썬과는 달리 자바에서는 char 과 String에 차이를 두고 문자와 문자열에 차이가 있다.
일단 2가지 다 기본형 변수이다.
char는 작은 따옴표를 이용하여 문자 한개만을 저장한다.
char alphabet = 'A'; // 문자 하나를 저장합니다.
문자열은 큰 따옴표를 사용하여 문자 여러개를 저장한다.
String message = "Hello World"; // 문자열을 저장합니다.
값들을 저장하는 관점에서는
- 문자 (char)
- 문자 뒤에 \0(널문자)가 없다. (1 byte만 쓰기 때문에 끝을 알아서 데이터만 저장하면 된다.)
- 문자열 (String)
- 문장의 끝에 \0(널문자)가 함께 저장이 된다. (몇 개의 byte를 쓸지 모르기 때문에 끝을 표시해야 한다.)
4. 참조형 변수
기본형 변수가 실제 값을 저장하는 저장 공간이라면 참조형 변수는 실제 값이 아닌 원본 값의 주솟값을 저장한다.
참조형 변수에는 문자열 변수, 배열 변수, 래퍼 클래스 변수가 있다.
- 저장 관점에서 차이점
- 기본형 변수 : 원본 값이 Stack 영역에 있다.
- 참조형 변수 : 원본 값이 Heap 영역에 있다.
- Stack 영역에는 따로 저장 해둔 원본 값의 Heap 영역 주소를 저장한다.

Stack 영역 vs Heap 영역
- Stack의 경우에는 정적으로 할당된 메모리 영역이다.
- 그래서, 크기가 몇 byte 인지 정해져 있는 기본형 변수를 저장한다.
- 추가로, 크기가 정해져 있는 참조형 변수의 주솟값도 저장한다.
- Heap의 경우에는 동적으로 할당된 메모리 영역이다.
- 그래서, 크기가 계속 늘어날 수 있는 참조형 변수의 원본을 저장한다.
5. Wrapper 클래스
래퍼 클래스(Wrapper Class)라는 말 그대로 “기본형 변수를 클래스로 한번 랩핑(감싸는) 변수”라고 생각하면된다.
그렇다면 래퍼클래스를 왜사용하는가?
클래스로 한번 감싸줌으로써 클래스에서 사용가능한 메서드들을 사용하기 위해서이다.
//박싱 > 기본형 타입을 클래스로 감싸주는 것이다.
int b = 4;
Integer n = b;
기본형 변수 int형 변수 b를 Integer 래퍼클래스로 다시 선언하였다.
//언박싱
System.out.println(n.intValue());
위와 같이 언박싱 할 때에 다양한 메서드를 사용할 수 있다.
모든 기본형 변수에는 다음과 같은 래퍼 클래스가 있다.

6. feature 브랜치에서 작업하다가 dev브랜치에 pr할 때
feature 브랜치에서 작업하다가 dev브랜치에 pr할 때 충돌이 발생할 수 도 있다.
따라서 충돌이 발생하거나 pr하기 전에 작업 중인 feature 브랜치에 dev브랜치를 pull 받아온다. 만약 충돌이 일어나면 충돌이 일어난 부분을 해결하고 다시 dev브랜치에 push해서 pr을 한다. 이렇게 하면 기능을 추가할 때 훨씬 더 안전하게 merge 할 수 있다.
그리고 pr 요청하면 리뷰어들에게 코드리뷰 보내는거 잊지말기!
[오늘 회고]
오늘은 자바 문법 기초를 집중적으로 학습하는 날이었다. 비록 1주차까지밖에 수강을 하지 못했지만 그 안에서도 배울게 많았다. 학부 시절 전혀 이해가 되지 않던 내용이 조금씩 이해가 되는 느낌이다. 왜 객체지향인지 조금은 알 수 있을 것 같기도 하다. 코드안에서 요소를 객체로 만들어서 현실과 동일시 하게 사용한다는 말이 new 연산자를 왜 사용해야하는지 알아볼때 조금은 와닿았던 것 같다.
오늘은 JVM 구성환경, 변수 타입 (기본형 변수, 참조형변수), 형변환에 대해서 배웠다.
'개발 회고 > TIL' 카테고리의 다른 글
| [1/6] TIL - 클래스변수 문제 해결, 객체와 클래스, 생성자, 오버로딩, 접근제어자, getter와 setter, this, super, 상속, 오버라이딩 (2) | 2025.01.06 |
|---|---|
| [1/2] TIL - 📚 오늘의 학습 정리: 연산자, 제어문, 배열, 콜렉션 자료구조, 객체와 생성자 (1) | 2025.01.02 |
| [12/30] TIL - 프로젝트 발표회에서 얻은 인사이트와 앞으로의 다짐 (4) | 2024.12.30 |
| [12/27] TIL - 팀 프로젝트 최종 마무리와 Git merge, HTML 연동 방법 학습 (3) | 2024.12.27 |
| [12/26] TIL (3) | 2024.12.26 |