
String : 문자들의 집합(문자열)을 표현하는 클래스이다.
String str = "Hello"; 형식으로 생성되며, 문자열 리터럴을 직접 사용할 수 있는 특별한 클래스이다.
한 번 생성된 String 객체의 내용은 변경할 수 없다.
String str = "Hello";
str = str + " World"; // 기존 "Hello"는 버려지고 새로운 "Hello World" 객체가 생성됨
문자열 리터럴은 JVM이 메모리 절약을 위해 풀(pool)에서 관리한다.
같은 문자열을 여러 번 생성해도 동일한 인스턴스를 공유한다.
String a = "Hello";
String b = "Hello";
System.out.println(a == b); // true (주소 비교, 동일 객체)
String s1 = "hello"; // 리터럴 방식 (문자열 풀에 저장)
String s2 = new String("hello"); // 명시적 생성 (heap에 새 객체)
문자열 "hello"는 "상수 풀(String Constant Pool)" 에 저장된다.
상수 풀은 힙 메모리 영역 내에 존재하지만 일반 객체처럼 관리되지 않는다.
"hello" 리터럴은 상수 풀에 존재하고,
new String("hello")는 힙 영역에 별도로 새 객체를 생성한다.
s1 == s2 → false (주소 다름), s1.equals(s2) → true (내용 같음)
메모리를 절약하고 성능을 향상시키기 위해 만들어진 특수한 저장 공간.
문자열뿐만 아니라 다른 종류의 상수와 참조 정보도 저장된다.
문자열 리터럴 (String Literals): 문자열 리터럴은 자동으로 상수 풀에 저장되며, 동일한 문자열은 공유됨
기본형 상수 (정수, 실수, 문자, boolean 등): final로 선언된 기본형 상수값들은 컴파일 시 상수 풀에 저장된다.
클래스, 메서드, 필드 이름 등 (바이트코드 수준에서): 컴파일된 .class 파일 안에는 java/lang/System, out, println, "Hello" 같은 문자열이나 심볼이 상수 풀 테이블(Constant Pool Table)에 저장되어 있음
| 메서드 | 설명 |
|---|---|
length() | 문자열 길이 반환 |
charAt(int index) | 특정 위치의 문자 반환 |
substring(int beginIndex, int endIndex) | 문자열 일부 추출 |
equals(String another) | 내용이 같은지 비교 (==는 주소 비교) |
equalsIgnoreCase(String another) | 대소문자 구분 없이 비교 |
indexOf(String str) | 특정 문자열의 위치 반환 |
contains(CharSequence s) | 문자열 포함 여부 |
toUpperCase(), toLowerCase() | 대소/소문자로 변환 |
trim() | 앞뒤 공백 제거 |
replace(String old, String new) | 문자열 치환 |
split(String regex) | 구분자 기준으로 문자열 분리 |
valueOf(int i) | 다른 타입을 문자열로 변환 |
static은 "정적(static)" 이라는 의미로, 클래스에 속한 구성요소를 정의할 때 사용된다.
인스턴스를 생성하지 않아도 클래스 이름으로 직접 접근할 수 있다.
클래스 로딩 시 메모리에 단 한 번만 생성되며 공유된다.
클래스에 딱 하나만 존재하며 모든 객체가 공유하는 변수.
package lesson04;
class Ex08_Car{
static int count =0;
public Ex08_Car(){
count++;
}
}
public class Ex08_Main {
public static void main(String[] args) {
new Ex08_Car();
new Ex08_Car();
new Ex08_Car();
System.out.println("총 생성된 자동차 수: "+Ex08_Car.count);
}
}
총 생성된 자동차 수: 3
객체 없이 호출 가능
package lesson04;
class Calculator{
public static int add(int a, int b){
return a + b;
}
}
public class Ex09_Main {
public static void main(String[] args) {
int result = Calculator.add(5,3);
System.out.println("결과: " + result);
}
}
결과: 8
클래스가 처음 로딩될 때 한 번만 실행된다.
class Config {
static int maxUsers;
static {
// 복잡한 초기화 코드
maxUsers = 100;
System.out.println("Config 클래스가 로딩되면서 초기화됨!");
}
}
public class Main {
public static void main(String[] args) {
System.out.println("최대 사용자 수: " + Config.maxUsers);
}
}
class ServerConfig {
static int port;
static String mode;
static {
System.out.println("static initializer 실행됨");
port = 8080;
mode = "production";
}
}
public class Main {
public static void main(String[] args) {
System.out.println("포트: " + ServerConfig.port);
System.out.println("모드: " + ServerConfig.mode);
}
}
static import를 사용하면 클래스명을 생략하고 static 멤버를 직접 쓸 수 있다.
package lesson04;
import org.w3c.dom.ls.LSOutput;
import static java.lang.Math.*;
public class Ex11_Main {
public static void main(String[] args) {
System.out.println(sqrt(16));
System.out.println(pow(2, 3));
}
}
4.0
8.0
| 장점 | 설명 |
|---|---|
| 메모리 절약 | 한 번만 생성되므로 메모리 사용량 감소 |
| 접근 편의 | 객체 생성 없이 클래스 이름으로 직접 접근 |
| 공유 용이 | 여러 객체가 같은 값을 공유할 때 유용 |
정의: 클래스의 인스턴스를 하나만 만들고, 어디서든 그 인스턴스에 접근할 수 있도록 하는 디자인 패턴
목적: 전역적으로 하나의 객체만 존재하도록 하여 메모리 낭비를 막고, 일관된 접근 방식을 제공
private 생성자 – 외부에서 객체 생성을 막음
private static 인스턴스 변수 – 클래스 내부에 유일한 인스턴스 보관
public static 메서드 (getInstance()) – 유일한 인스턴스를 외부에 제공
package lesson04;
class Singleton {
private static final Singleton instance = new Singleton();
private Singleton(){
System.out.println("싱글톤 객체 생성됨");
}
public static Singleton getInstance(){
return instance;
}
public void printMessage(){
System.out.println("싱글톤 패턴으로 실행 중입니다.");
}
}
public class Ex12_Main {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
s1.printMessage();
System.out.println(s1 == s2);
}
}
싱글톤 객체 생성됨
싱글톤 패턴으로 실행 중입니다.
true
디자인 패턴
사용이유
디자인 패턴 3가지
GoF 디자인 패턴
싱글톤 패턴 - 생성 패턴 중 하나