Java Modifiers
자바 수정자 (Java Modifiers): 개념 및 사용법
자바 수정자(Modifiers)는 클래스, 메서드, 변수 등에 특정한 속성을 부여하여 동작 방식을 제어하는 역할을 합니다. 수정자를 사용하면 클래스나 구성 요소의 가시성, 동작 방식, 사용 범위 등을 제어할 수 있습니다. 자바에서 제공하는 수정자는 크게 **접근 제어자(Access Modifiers)**와 **기타 수정자(Other Modifiers)**로 나뉩니다. 이 글에서는 자바 수정자의 종류와 사용법에 대해 설명합니다.
1. 접근 제어자 (Access Modifiers)
접근 제어자는 클래스, 메서드, 변수, 생성자 등의 접근 범위를 정의하는 수정자입니다. 접근 제어자는 네 가지가 있습니다:
- public
- private
- protected
- default (접근 제어자를 명시하지 않은 경우)
1.1 public
public
으로 선언된 클래스나 멤버는 어디서든 접근할 수 있습니다. 모든 패키지나 클래스에서 접근 가능하므로 범위가 가장 넓습니다.
예제: public
접근 제어자
public class Car {
public String model;
public int year;
public void displayInfo() {
System.out.println("Model: " + model + ", Year: " + year);
}
}
1.2 private
private
로 선언된 멤버는 해당 클래스 내에서만 접근할 수 있으며, 외부에서는 접근할 수 없습니다. 주로 클래스 내부에서만 사용해야 하는 속성이나 메서드를 보호하는 데 사용됩니다.
예제: private
접근 제어자
class Car {
private String model;
private int year;
// private 필드에 접근하기 위해 public 메서드를 제공
public void setModel(String model) {
this.model = model;
}
public String getModel() {
return model;
}
}
1.3 protected
protected
로 선언된 멤버는 동일한 패키지 내의 클래스 또는 상속받은 클래스에서 접근할 수 있습니다. 주로 상속 관계에서 자식 클래스에서 부모 클래스의 멤버를 사용할 수 있도록 할
때 사용됩니다.
예제: protected
접근 제어자
class Vehicle {
protected String type;
protected void startEngine() {
System.out.println("Engine started.");
}
}
class Car extends Vehicle {
public void showType() {
System.out.println("Vehicle type: " + type);
}
}
1.4 default
(접근 제어자를 명시하지 않은 경우)
접근 제어자를 명시하지 않으면 default 접근 수준이 적용되며, 동일한 패키지 내에서만 접근할 수 있습니다. 이 접근 범위를 패키지 접근이라고도 합니다.
예제: default
접근 제어자
class Car {
String model; // default 접근 제어자 (명시되지 않음)
int year;
void displayInfo() {
System.out.println("Model: " + model + ", Year: " + year);
}
}
접근 제어자의 요약
접근 제어자 | 같은 클래스 | 같은 패키지 | 상속받은 클래스 | 모든 클래스 |
---|---|---|---|---|
public |
O | O | O | O |
protected |
O | O | O | X |
default |
O | O | X | X |
private |
O | X | X | X |
2. 기타 수정자 (Other Modifiers)
접근 제어자 외에도 자바는 클래스, 메서드, 변수 등에 부여할 수 있는 여러 가지 다른 수정자를 제공합니다. 여기에는 static
, final
,
abstract
, synchronized
, volatile
, transient
등이 포함됩니다.
2.1 static
static
수정자는 클래스 레벨에서 사용되며, 클래스에 속한 변수나 메서드임을 나타냅니다. static
으로 선언된 변수나 메서드는 객체가 아닌 클래스 자체에서
접근할 수 있습니다.
예제: static
수정자
class Car {
static int numberOfCars = 0;
public Car() {
numberOfCars++;
}
public static int getNumberOfCars() {
return numberOfCars;
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car();
Car car2 = new Car();
System.out.println(Car.getNumberOfCars()); // 출력: 2
}
}
2.2 final
final
수정자는 클래스, 메서드, 변수 등에 사용되며, 변경할 수 없는 요소를 정의합니다.
final
클래스는 상속할 수 없습니다.final
메서드는 오버라이딩할 수 없습니다.final
변수는 값을 한 번만 할당할 수 있습니다.
예제: final
수정자
class Vehicle {
public final void startEngine() {
System.out.println("Engine started.");
}
}
class Car extends Vehicle {
// startEngine() 메서드는 final이므로 오버라이딩할 수 없음
}
2.3 abstract
abstract
수정자는 추상 클래스와 추상 메서드를 정의할 때 사용됩니다.
- 추상 클래스는 객체를 생성할 수 없으며, 다른 클래스가 상속받아야 합니다.
- 추상 메서드는 선언만 하고, 구현은 상속받는 클래스에서 반드시 제공해야 합니다.
예제: abstract
수정자
abstract class Animal {
// 추상 메서드
public abstract void makeSound();
public void sleep() {
System.out.println("Sleeping...");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Bark");
}
}
2.4 synchronized
synchronized
수정자는 멀티스레딩 환경에서 한 번에 하나의 스레드만 해당 메서드에 접근하도록 제한할 때 사용됩니다.
예제: synchronized
수정자
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
2.5 volatile
volatile
수정자는 멀티스레드 환경에서 변수의 값을 각 스레드가 캐싱하지 않고, 항상 메인 메모리에서 읽도록 보장합니다. 이는 변수의 최신 값을 모든 스레드가 항상 사용할 수 있게
만듭니다.
2.6 transient
transient
수정자는 직렬화(Serialization)할 때 해당 변수의 값을 직렬화하지 않도록 할 때 사용됩니다. 직렬화는 객체를 저장하거나 전송하기 위한 과정으로,
transient
로 선언된 변수는 이 과정에서 제외됩니다.
예제: transient
수정자
import java.io.*;
class Car implements Serializable {
public String model;
public transient int year; // 직렬화에서 제외됨
public Car(String model, int year) {
this.model = model;
this.year = year;
}
}
요약
자바에서 제공하는 여러 수정자를 통해 클래스, 메서드, 변수 등의 동작을 세밀하게 제어할 수 있습니다.
public
,private
,protected
,default
: 접근 제어자를 사용하여 클래스와 멤버의 접근 범위를 정의합니다.static
: 클래스 자체에 속하는 변수나 메서드를 정의합니다.final
: 변경할 수 없는 클래스, 메서드, 변수 등을 정의합니다.abstract
: 구현되지 않은 추상 클래스를 정의하여 상속을 요구합니다.synchronized
: 멀티스레드 환경에서 동시 접근을 제한합니다.volatile
: 최신 값을 모든 스레드가 사용하도록 보장합니다.transient
: 직렬화 과정에서 제외할 변수를 정의합니다.
수정자를 적절히 활용하면 코드의 안정성과 재사용성을 높이고, 객체 지향 프로그래밍의 특성을 더 잘 살릴 수 있습니다.