본문 바로가기

Java/Java SE, EE

[Java/Java SE, EE] 접근 지정자(Access Modifier)와 접근자(getter), 수정자(setter)

접근 지정자(Access Modifier)

자바에서는 접근 지정자를 사용하여 클래스(Class), 필드(Field), 메소드(Method), 정적 필드(Static field), 정적 메소드(Static method), 열거 타입(Enumeration type) 등에 대한 접근 범위를 결정합니다.

자바에서 사용 할 수 있는 접근 지정자는 다음과 같습니다. public 접근 지정자에서부터 private 접근 지정자까지 더 엄격한 접근 제한 규칙을 갖습니다.

  • public
  • protected
  • default
  • private

public

public 접근 지정자는 모든 코드에서의 접근 제한이 없습니다. 클래스의 경우 외부에서 호출하는 메소드의 경우 public 키워드를 사용합니다. 자바는 OOP 이므로, 캡슐화를 위해서 일반적인 경우라면 클래스의 필드는 public 키워드를 권장하지 않습니다.

public class Car 
{
   public int some_field;
   public int some_method() { return 0; }
}
접근 지정자 접근 범위
public 모든 외부 접근 허용

protected

protected 접근 지정자는 동일한 패키지 또는 상속 관계에서 부모 클래스의 필드, 메소드, 정적 필드와 정적 메소드에 대한 접근을 허용합니다. 자바의 패키지(Package)는 물리적으로 하나의 디렉토리를 의미합니다. 패키지는 밀접하게 연관있는 클래스, 인터페이스, 열거 타입 등의 집합입니다. 다시말해서 protected 키워드는 밀접한 연관 관계를 갖는 클래스 등에게 자신의 데이터 또는 메소드의 접근을 허용하기 위해서 사용합니다.

public class Car
{
   protected int some_field;
   protected int some_method() { return 0; }
}

추가로 클래스를 선언할 때 protected 키워드를 허용하지 않습니다. 따라서 다음 같은 코드는 작성이 불가능합니다.

protected class Car	// not allowed this access modifier
{
}
접근 지정자 접근 범위
public 모든 외부 접근 허용
protected 동일한 패키지 또는 상속 관계에서 부모 클래스의 필드와 메소드 등에 대한 접근 허용

default

코드에서 별도의 키워드를 붙이지 않은 경우, 자동으로 default 키워드가 적용됩니다. 이 키워드는 protected 키워드 보다 조금 더 엄격한 수준의 접근 제한자입니다. protected 키워드처럼 같은 패키지 내에서의 접근을 허용하지만, 패키지가 다른 경우 상속 관계에서의 접근까지는 허용하지 않습니다.

public class Car
{
   int some_field;
   int some_method() { return 0; }
}
접근 지정자 접근 범위
public 모든 외부 접근 허용
protected 동일한 패키지 또는 상속 관계에서 부모 클래스의 필드와 메소드 등에 대한 접근 허용
default 동일한 패키지의 접근 허용

private

private 키워드는 자기 자신을 제외한 모든 외부의 접근을 제한하는, 가장 엄격한 접근 제한자입니다. 

public class Car
{
   private int some_field;
   private int some_method() { return 0; }
}

protected 키워드와 마찬가지로, 클래스를 선언할 때 private 키워드를 허용하지 않습니다. 따라서 다음 같은 코드는 작성이 불가능합니다.

private class Car	// not allowed this access modifier
{
}
접근 지정자 접근 범위
public 모든 외부 접근 허용
protected 동일한 패키지 또는 상속 관계에서 부모 클래스의 필드와 메소드 등에 대한 접근 허용
default 동일한 패키지의 접근 허용
private 모든 외부 접근 차단

접근자(getter), 수정자(setter)

자바는 클래스를 작성 할 때 캡슐화에 대해서 고려해야 합니다. 캡슐화는 기본적으로 필드를 숨기는 것부터 시작합니다. 클래스의 필드를 외부에서 접근하지 못하게 하기 위해, protected 또는 private 키워드를 사용합니다. 클래스가 상속 관계를 갖는 경우, 자식 클래스는 부모 클래스의 필드 또는 메소드에 명시적으로 접근 허용(protected) 또는 접근 불가(private)합니다. default 키워드의 경우 상속 관계에 대한 접근 허용 범위가 모호하기 때문에 캡슐화의 목적으로는 잘 사용되지 않습니다.

필드에 대한 접근 제한자가 protected 이상으로 엄격해지면, 외부에서는 해당 필드에 접근할 방법이 없습니다. 이를 위해 캡슐화에서는 접근자(getter)와 수정자(setter) 메소드를 구현하여 사용하는 것을 권장합니다.

public class Car
{
   private int some_field;
 
   // getter
   public int getSome_field() {
      return some_field;
   }
   
   // setter
   public void setSome_field(int _some_field) {
      some_field = _some_field;
   }
}

접근자(getter) 메소드는 캡슐화로 은닉된 필드에 액세스하기 위한 통로입니다. 마찬가지로 수정자(setter) 메소드는 은닉된 액세스의 값을 수정하기 위한 통로입니다.

getter와 setter를 사용하는 이유는 필드에 대한 접근 코드 또는 수정 코드에 대해서 외부 사용에 대한 일관성을 제공 할 수 있다는 점입니다. 다음은 앞의 예시에서 작성한 getter와 setter를 수정하였습니다. getter와 setter 내부의 로직을 변경하면, 자동으로 외부에서 접근하는 모든 코드가 변경된 로직의 일관성을 따르기 때문에 유지 보수에 용의하고 버그 발생 가능성이 헌저히 낮아집니다.

public int getSome_field() {
   return some_field * 2;
}

public void setSome_field(int _some_field) {
   some_field = _some_field / 2;
}

 

대부분의 IDE에서는 getter와 setter에 대한 구현을 자동으로 지원합니다. IntelliJ에서는 상단 도구 바에서 [Code > Generate] 또는 클래스나 필드에서 [마우스 오른쪽 클릭 > Generate]를 사용합니다.

IntelliJ의 getter,setter 자동 구현