프로그래밍/JAVA

java 문자열

Cognivox 2025. 4. 7. 16:30
반응형

문자열의 개요

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