반응형
✅ 문자열의 개요
1. 문자열이란?
- 문자들의 **연속(배열)**이야.
- 쉽게 말해: 'Hello World'는 → 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' 이런 문자 하나하나가 연결된 구조!
2. 공백도 문자다
- ' ' ← 공백도 문자로 취급됨
→ 예: 'H', ' '(스페이스), 'W'
3. 문자열은 항상 큰따옴표로 씀
- 작은따옴표 'a'는 문자 1개(char)
- 큰따옴표 "abc"는 문자열(String)
4. 문자열은 String 클래스의 객체

- 이건 단순 텍스트가 아니라 **String이라는 클래스의 객체(인스턴스)**야.
5. new 키워드를 쓰면 메모리에 따로 생성됨

- 이렇게 하면 Heap 메모리에 새로운 객체가 생성돼.
- "Hello" 이렇게 쓰면 **문자열 상수 풀(String Pool)**에 저장됨.
📌 정리 요약
구분예시의미
문자열 선언 | String s = "hi"; | String 객체 (문자열) |
문자의 나열 | "Hi" → 'H', 'i' | 문자들의 배열 |
공백도 문자 | " " | 문자 하나로 취급 |
char vs String | 'A' vs "A" | 문자 vs 문자열 |
메모리 구조 | new String() | 동적으로 따로 저장됨 |
이 이미지는 Java에서 문자열을 선언하는 두 가지 방식을 설명하고 있음.
같은 "Java"라는 문자열이지만, 메모리에 저장되는 방식이 다르다는 걸 보여주는 그림👇
✅ 그림 속 설명 정리
🔹 1. String myStr = "Java"; ← 리터럴 방식
- "Java"라는 문자열은 String Constant Pool(문자열 상수 영역)에 저장됨
- myStr는 이 메모리에 저장된 "Java"를 참조함
- 동일한 "Java" 리터럴이 또 있으면 → 기존 메모리 재사용
✅ 장점: 메모리 절약, 속도 빠름
✅ 추천: 일반적인 문자열 선언 시
🔹 2. String myStr = new String("Java"); ← 객체 생성 방식
- "Java"라는 리터럴이 먼저 상수 풀에 들어감
- 그다음 new String()이 호출되며 → Heap 영역에 새로운 객체가 생성됨
- myStr는 Heap에 있는 별도의 새 String 객체를 참조함
✅ 단점: 불필요하게 메모리를 더 씀
✅ 사용 예시: 꼭 새 인스턴스를 따로 만들어야 할 때 (예: 객체 비교 테스트 등)
📌 왜 이게 중요하냐?
▶ 아래 코드 비교해보면:

💡 결론 요약
방식코드 예시저장 위치주소 같음?추천
리터럴 | "Java" | 상수 풀 (String Pool) | 같음 | 대부분 이 방식 사용 |
new 객체 | new String("Java") | Heap | 다름 | 특별한 경우에만 사용 |
"문자열 리터럴 vs 객체", 그리고 "배열에서 new 사용 여부"
→ 이 둘은 Java의 메모리 구조와 객체 생성 원리랑 관련 있음. 간단하고 명확하게 정리 👇
✅ 1. 문자열 리터럴 vs new String()
🔹 리터럴 방식

- "hello"는 **문자열 상수 풀(String Pool)**에 저장됨
- a와 b는 동일한 메모리 주소를 참조함 (== true)
✅ 메모리 절약 + 빠름
🔹 new String() 방식

- 각각 Heap 영역에 새로운 객체가 생성됨
- a와 b는 내용은 같아도 주소는 다름 (== false, equals()는 true)
✅ 꼭 새 객체가 필요한 경우에만 사용
🔑 요약
구분리터럴new String()
메모리 | String Pool | Heap |
주소 같음 | 예 (동일 값이면) | 아님 (매번 새로 생성) |
속도 | 빠름 | 느림 |
추천 | 일반적으로 사용 | 특수한 상황만 사용 |
✅ 2. 배열: 언제 new 쓰고, 언제 안 써?
🔹 new 쓰는 경우

- 배열의 크기를 직접 지정할 때
- 메모리 공간을 동적으로 확보함
🔹 new 안 쓰는 경우 (리터럴 방식)

- 값을 직접 넣고 초기화할 때
- 크기를 자동으로 판단함
🔑 요약
구분new 사용new 없이 리터럴 사용
형태 | new int[5] | {1, 2, 3} |
특징 | 크기만 정하고 나중에 채움 | 값과 크기 동시에 설정 |
메모리 | Heap에 공간 생성 | Heap에 생성 (하지만 코드 간결) |
추천 | 동적 상황 | 고정된 값 설정 시 |
✨ 예시로 이해

✅ 왜 리터럴 형(String 리터럴)을 많이 쓸까?
✔ 이유 1: 메모리 절약 (String Constant Pool 사용)
- "Hello"처럼 큰따옴표로 쓴 문자열은
→ **String Constant Pool(상수 풀)**에 저장됨 - 같은 값이 나오면 기존 걸 재사용

✔ 이유 2: 성능 빠름 (객체 재사용)
- new String("hello")는 Heap에 객체를 따로 생성해서
→ 메모리 낭비 + 속도 느림
✅ 문자열을 선언하는 두 가지 방법
방식예시 코드메모리 위치특징
1️⃣ 리터럴 방식 | String str = "hi"; | 상수 풀 | ⭐ 가장 많이 사용 |
2️⃣ new 방식 | String str = new String("hi"); | Heap 영역 | ❗ 특별한 경우만 사용 |
📌 핵심 정리 문장
문자열은 리터럴 형으로 선언하는 것이 기본이다.
리터럴 방식은 상수 풀을 사용해 메모리 절약과 성능 면에서 효율적이다.
문자열 선언 방식은
👉 "문자열" (리터럴)
👉 new String("문자열")
이렇게 두 가지가 있다.
💡 비교 요약
구분리터럴 방식 (String str = "hi";)객체 방식 (new String("hi"))
메모리 위치 | String Constant Pool | Heap |
객체 생성 | 1번만 (재사용) | 호출할 때마다 새 객체 |
== 비교 | true (같은 주소) | false (주소 다름) |
성능 | 빠르고 효율적 | 느리고 비효율적 |
추천 | ✅ 일반적 사용 | ❗ 특별한 이유 있을 때만 |
✅ 자주 사용하는 String 메서드 요약
메서드반환 타입역할
length() | int | 문자열 길이 반환 |
isEmpty() | boolean | 비었는지 확인 (""이면 true) |
charAt(index) | char | 특정 위치 문자 반환 |
substring(start) | String | 시작 위치부터 끝까지 자름 |
substring(start, end) | String | 시작 ~ 끝-1 까지 자름 |
concat(str) | String | 문자열 이어붙이기 (A + B) |
indexOf(char) | int | 문자가 처음 등장하는 위치 |
equals(obj) | boolean | 문자열 값 비교 (== 아님!) |
compareTo(obj) | int | 사전순 비교 (0:같음, <0:작음, >0:큼) |
toLowerCase() | String | 모두 소문자로 변환 |
toUpperCase() | String | 모두 대문자로 변환 |
trim() | String | 앞뒤 공백 제거 |
replace(old, new) | String | 특정 문자 바꾸기 |
✨ 실전 예제 요약

🧠 기억할 포인트
- == ❌ → .equals()로 문자열 비교
- 공백 제거: .trim()
- 문자 바꾸기: .replace()
- 문자열 자르기: .substring()
- 문자열 길이: .length()
이 이미지는 Java의 String 클래스에서 제공하는 주요 메서드들을 시각적으로 설명한 그림
✅ 문자열: "Java Programming"
이 문자열은 s라는 변수에 저장되어 있다고 가정함.
1. s.charAt(1)
- 설명: 문자열에서 인덱스 1에 해당하는 문자 반환
- 결과: 'a'
("Java Programming"의 두 번째 글자 → 0부터 시작함)
2. s.substring(6)
- 설명: 인덱스 6부터 끝까지 잘라낸 문자열 반환
- 결과: "Programming"
(`6번 인덱스는 'P'부터 시작)
3. s.substring(5, 13)
- 설명: 인덱스 5부터 12까지 (13은 포함하지 않음)
- 결과: "Programming"
(5번 인덱스 ' ' 공백부터 12번 인덱스 'g'까지)
4. s.indexOf("P")
- 설명: 문자열에서 'P'가 처음 등장하는 위치(인덱스)를 반환
- 결과: 6
5. s.length()
- 설명: 문자열의 길이 반환
- 결과: 18
(인덱스는 0부터 17까지 총 18글자)
6. s.toLowerCase() / s.toUpperCase()
- 설명:
- toLowerCase(): 모든 문자를 소문자로 변환
- toUpperCase(): 모든 문자를 대문자로 변환
- 예시:
- "Java Programming".toLowerCase() → "java programming"
- "Java Programming".toUpperCase() → "JAVA PROGRAMMING"
📌 참고 요약
메서드설명결과
s.charAt(1) | 1번 인덱스 문자 | 'a' |
s.substring(6) | 6번부터 끝까지 | "Programming" |
s.substring(5,13) | 5~12번 문자 | " Programming" |
s.indexOf("P") | 'P' 위치 | 6 |
s.length() | 문자열 길이 | 18 |
s.toLowerCase() | 모두 소문자 | "java programming" |
s.toUpperCase() | 모두 대문자 | "JAVA PROGRAMMING" |
💡 JVM (Java Virtual Machine)이란?
JVM은 자바 프로그램이 돌아가는 가상 머신이야.
- 자바 코드는 .java 파일 → 컴파일되면 .class 파일(바이트코드)이 돼
- 이 .class 파일을 실행시키는 게 JVM
- 즉, 자바 코드를 운영체제와 무관하게 실행하게 해주는 가상 환경
🧠 그럼 JVM 안에 있는 "메모리 구조"는?
JVM 안에는 여러 메모리 영역이 있어. 그 중 자주 나오는 두 가지가:
1️⃣ Heap (힙 메모리)
- new 키워드로 만든 객체들이 저장되는 공간
- 런타임 중 동적으로 생성되는 객체
- 예: new String("Hello"), new Student()
2️⃣ String Constant Pool (문자열 상수 풀)
- 문자열 리터럴을 저장하는 특별한 영역
- 중복된 문자열 리터럴은 재사용함 (메모리 아끼려고)
- 예: "Hello" 리터럴 여러 번 써도 같은 곳 참조
🔍 예제 코드로 보자

🔸 메모리 저장 위치 비교
변수저장 위치설명
s1, s2 | 상수 풀 (String Constant Pool) | 같은 리터럴 → 같은 객체 공유함 |
s3 | 힙 (Heap) | new 키워드 → 무조건 새 객체 생성 |
✅ 언제 어디에 저장되는지 정리!
생성 방식저장 위치특징
"Hello" | 상수 풀 | 문자열 리터럴, JVM이 자동 저장 및 재사용 |
new String("Hello") | 힙 | 새로운 객체 생성, 상수 풀과 주소 다름 |
📌 결론 요약
구분의미예시
힙(Heap) | 동적으로 생성된 객체 저장 | new Student(), new String("Hi") |
상수 풀(Constant Pool) | 리터럴 문자열 저장 (재사용됨) | "Hi", "Java" |
#Java #JVM #Java기초 #문자열비교 #String #StringPool #Heap메모리 #상수풀 #Java문법 #equals #new연산자 #Java개념 #객체비교 #자바초보 #자바학습 #자바문자열 #자바객체 #JVM구조 #Java개발 #Java프로그래밍
반응형
'프로그래밍 > JAVA' 카테고리의 다른 글
화이트박스 테스트 or 블랙박스 테스트 (0) | 2025.04.08 |
---|---|
유클리드 호제법 (0) | 2025.04.07 |
자바로 만들 수 있는 것들 (기초부터 실무까지) (0) | 2025.04.07 |
java 2차원 배열 (0) | 2025.04.07 |
java 상수란? (0) | 2025.04.07 |