자바에서는 클래스, 변수, 메서드의 접근 권한을 제한하여 보안성을 높이고 코드의 유지보수를 쉽게 할 수 있다.
접근 제어자 | 설명 | 접근 가능 범위 |
---|---|---|
public | 모든 클래스에서 접근 가능 | 어디서든 접근 가능 |
private | 해당 클래스 내에서만 접근 가능 | 외부 접근 불가능 (정보 은닉) |
protected | 같은 패키지 + 상속 관계의 클래스에서 접근 가능 | 패키지 내부 또는 상속 관계에서만 접근 가능 |
(default) | 아무 키워드도 작성하지 않으면 기본 적용 | 같은 패키지 내에서만 접근 가능 |
class Person {
private String name; // private 멤버 변수 (직접 접근 불가능)
protected int age; // protected 멤버 변수
public String address; // public 멤버 변수
// 생성자
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
// private 변수 접근을 위한 getter 메서드
public String getName() {
return this.name;
}
}
private
변수는 외부에서 직접 접근할 수 없음 → getter/setter 사용protected
변수는 같은 패키지 또는 상속 관계에서만 접근 가능public
변수는 어디서든 자유롭게 접근 가능캡슐화란?
class Engine {
private void 흡입() { System.out.println("공기 흡입"); }
private void 압축() { System.out.println("공기 압축"); }
private void 폭발() { System.out.println("연료 폭발!"); }
private void 배기() { System.out.println("배기 가스 배출"); }
public void startEngine() {
흡입();
압축();
폭발();
배기();
}
}
class Car {
private Engine engine; // 엔진을 캡슐화하여 외부에서 직접 접근 불가능
public Car() {
engine = new Engine();
}
public void run() {
engine.startEngine(); // 자동차를 작동시키면 내부적으로 엔진이 작동됨
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.run();
}
}
✔ 캡슐화를 통해 내부 동작을 숨김 → 유지보수성 증가
✔ 외부에서는 Car
의 run()
메서드만 호출하면 내부적으로 Engine
이 동작
✔ 내부 동작이 변경되더라도 외부 코드에는 영향을 주지 않음
this
키워드this
란?this
는 현재 객체의 참조를 의미하는 키워드로, 다음과 같은 용도로 사용됨.
this
의 주요 기능1️⃣ 멤버 변수와 지역 변수 구별
class Person {
private String name;
public Person(String name) {
this.name = name; // 멤버 변수와 지역 변수 구별
}
}
2️⃣ 다른 생성자 호출 (this(...)
)
class Example {
int x, y;
Example() {
this(0, 0); // 다른 생성자 호출
}
Example(int x, int y) {
this.x = x;
this.y = y;
}
}
3️⃣ 현재 객체 반환 (return this
)
class Example {
Example getThis() {
return this;
}
}
String
객체와 문자열 연결concat()
메서드concat()
메서드는 두 개의 문자열을 이어붙일 때 사용 String
은 불변 객체(Immutable) 이므로 concat()
을 사용할 때마다 새로운 객체가 생성됨 → 메모리 비효율적 concat()
예제String str1 = "Java";
String str2 = " Programming";
String str3 = str1.concat(str2); // 새로운 문자열 생성됨
System.out.println(str3); // Java Programming
String
vs StringBuilder
vs StringBuffer
타입 | 특징 | 사용 추천 |
---|---|---|
String | 불변(Immutable), 메모리 낭비 | 변경이 적을 때 |
StringBuilder | 가변(Mutable), 빠름 | 단일 스레드 환경 |
StringBuffer | 가변(Mutable), 동기화 지원 | 멀티스레드 환경 |
concat()
vs StringBuilder.append()
String str = "";
for (int i = 0; i < 10; i++) {
str = str.concat(String.valueOf(i)); // 매 반복마다 새로운 객체 생성됨 ❌
}
System.out.println(str);
✔ 위 코드는 concat()
을 반복 사용하여 메모리 낭비 발생
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < 10; i++) {
sb.append(i); // 같은 객체에서 문자열 수정 (메모리 효율적) ✅
}
System.out.println(sb);
✔ StringBuilder.append()
를 사용하면 객체를 새로 생성하지 않고 기존 객체를 수정함 → 성능 최적화 🚀
String
의 +
연산자와 concat()
비교String str1 = "Hello";
String str2 = " World";
String result1 = str1 + str2; // 내부적으로 StringBuilder 사용 (최적화)
String result2 = str1.concat(str2); // 새로운 String 객체 생성
System.out.println(result1); // Hello World
System.out.println(result2); // Hello World
✅ +
연산자는 내부적으로 컴파일러가 StringBuilder
로 변환하여 최적화
✅ concat()
은 새로운 객체를 생성하므로 메모리 낭비 발생
StringBuilder
와 StringBuffer
타입 | 특징 | 사용 추천 |
---|---|---|
String | 불변(Immutable), 메모리 낭비 | 변경이 적을 때 |
StringBuilder | 가변(Mutable), 빠름 | 단일 스레드 환경 |
StringBuffer | 가변(Mutable), 동기화 지원 | 멀티스레드 환경 |
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World"); // 기존 객체에서 문자열 수정 (메모리 절약)
System.out.println(sb); // Hello World
✔ StringBuilder
를 사용하면 새로운 객체를 생성하지 않고 문자열을 수정할 수 있음
✔ 반복문에서 +=
대신 StringBuilder.append()
사용!
String
을 사용한 문자열 덧붙이기 (비효율적)int i = 0;
String str = "";
while (i < 10) {
str += i;
System.out.print("str : " + str + " ");
System.out.printf("위치 : %X\n", System.identityHashCode(str));
i++;
}
❌ +=
연산을 사용할 때마다 새로운 String
객체가 생성됨
❌ 반복문을 돌릴수록 메모리 낭비 발생
StringBuilder
를 사용한 문자열 덧붙이기 (메모리 절약)int i = 0;
StringBuilder str = new StringBuilder("");
while (i < 10) {
str.append(i); // += 대신 append() 사용
System.out.print("str : " + str + " ");
System.out.printf("위치 : %X\n", System.identityHashCode(str));
i++;
}
✅ 메모리 주소가 동일함! (System.identityHashCode()
결과 같음)
✅ append()
사용 시 기존 객체를 수정하므로 메모리 낭비 없음
✅ 훨씬 빠르고 효율적
str : 0 위치 : 3FCD7E
str : 01 위치 : 3FCD7E
str : 012 위치 : 3FCD7E
str : 0123 위치 : 3FCD7E
str : 01234 위치 : 3FCD7E
str : 012345 위치 : 3FCD7E
str : 0123456 위치 : 3FCD7E
str : 01234567 위치 : 3FCD7E
str : 012345678 위치 : 3FCD7E
str : 0123456789 위치 : 3FCD7E
→ StringBuilder
를 사용하면 주소값이 변하지 않음!
concat()
은 String
을 연결할 때 사용 가능하지만, 새로운 객체를 생성하기 때문에 비효율적 StringBuilder.append()
를 사용하는 것이 좋음! +=
연산자를 남발하면 메모리 낭비가 심하므로 StringBuilder
를 활용할 것 ✔ 접근 한정자 (private
, public
, protected
)로 정보 보호
✔ 캡슐화 (private
변수 + public
메서드)로 내부 동작 숨기기
✔ this
로 객체 참조 및 생성자 재사용
✔ 문자열 비교는 .equals()
사용 (==
은 주소 비교)
✔ 문자열 연결은 StringBuilder
가 더 효율적! (concat()
은 메모리 낭비)