접근 제어자의 종류
- private : 모든 외부 호출 제한 (같은 클래스 내부에서만 허용)
- default (package-private) : 같은 패키지안에서 호출 허용
- protected : 같은 패키지안에서 호출 허용, 패키지가 달라도 상속 관계의 호출 허용
- public : 모든 외부 호출 허용
가장 많이 차단 ( private -> default -> protected -> public) 가장 많이 허용
package-private( = default)
접근 제어자를 명시하지 않으면 같은 패키지 안에서 호출을 허용하는 defalut 접근 제어자 적용
default : 접근 제어자의 기본값으로 사용되기 때문에 붙여진 이름
package-private : 더 정확한 표현이다. 왜냐면, 이 접근 제어자를 사용하는 멤버는 동일한 패키지 내의 다른 클래스에서만 접근이 가능하기 때문이다.
두 용어 함께 사용하므로 둘 다 알아 두도록 하자!
접근 제어자 사용 위치
접근 제어자는 필드(변수)와 메서드, 생성자에 사용 + 클래스 레벨에도 일부 접근제어자 사용 가능
사용 예시)
public class Speaker { // 클래스 레벨
private int volume; // 필드(변수)
public Speaker(int volume) {} // 생성자
public void volumeUP() {} // 메서드
public void volumeDown() {}
public void shwVolume() {}
}
*** 접근 제어자의 핵심은 속성과 기능을 외부로부터 숨기는 것이다. ***
private : 나의 클래스 안으로 속성과 기능을 숨길 때 사용, 외부 클래스에서 호출(접근) X
default : 나의 패키지 안으로 속성과 기능을 숨길 때 사용, 외부 패키지에서 호출(접근) X
protected : 상속 관계로 속성과 기능을 숨길 때 사용, 상속 관계가 아닌 곳에서 호출(접근) X
public : 기능을 숨기지 않고 어디서든 호출 가능
***참고
지역 변수는 접근 제어자 사용 X : 어차피 그 지역 안에서만 사용할 수 있어 접근 제어자 자체가 의미가 없다!
아래는 예제 코드 이다
package javabasic.access.a 패키지
package javabasic.access.a;
public class AccessData {
public int publicField;
int defaultField;
private int privateField;
public void publicMethod() {
System.out.println("publicMethod 호출 " + publicField);
}
void defaultMethod() {
System.out.println("defaultMethod 호출 " + defaultField);
}
private void privateMethod() {
System.out.println("privateMethod 호출 " + privateField);
}
// 자기 자신에게 접근 (private 포함)
public void innerAccess() {
System.out.println("내부 호출");
publicField = 100;
defaultField = 200;
privateField = 300;
publicMethod();
defaultMethod();
privateMethod();
}
}
package javabasic.access.a;
public class AccessInnerMain {
public static void main(String[] args) {
AccessData data = new AccessData();
// public 호출
data.publicField = 100;
data.publicMethod();
// 같은 패키지 default 호출
data.defaultField = 200;
data.defaultMethod();
// private 호출 불가 -> AccessData 내부에서만 접근 가능
// data.privateField = 300;
// data.privateMethod();
// public 메서드 호출
data.innerAccess();
}
}
** data.innerAccess() 메서드는 public -> 외부에서 호출 가능
innerAccess()는 외부에서 호출되었지만 AccessData에 포함되어 있으므로 innerAccess()는 자신의 private필드와 메서드에 모두 접근이 가능하다.
출력 결과 ↓

package javabasic.access.b 패키지
package javabasic.access.b;
import javabasic.access.a.AccessData;
public class AccessOuterMain {
public static void main(String[] args) {
AccessData data = new AccessData();
// public 호출
data.publicField = 100;
data.publicMethod();
// 다른 패키지 default 호출 불가
// data.defaultField = 200;
// data.defaultMethod();
// private 호출 불가
// data.privateField = 300;
// data.privateMethod();
// public 메서드 호출
data.innerAccess();
}
}
public은 모든 접근 허용
default는 같은 패키지에서만 접근 가능
출력 결과 ↓

** 생성자도 접근 제어자 관점에서 메서드와 같다!
접근 제어자 - 클래스 레벨
클래스 레벨의 접근 제어자 규칙
- 클래스 레벨 접근 제어자는 public, default만 사용 가능
- private, protected 사용 불가
- public 클래스는 반드시 파일명과 이름이 같아야 한다.
- 하나의 자바 파일에 public 클래스는 하나!!
- 하나의 자바 파일에 default 접근 제어자를 사용하는 클래스는 제한이 없다.
package javabasic.access.a 패키지
package javabasic.access.a;
// public 클래스
public class PublicClass {
public static void main(String[] args) {
PublicClass publicClass = new PublicClass();
DefaultClass1 class1 = new DefaultClass1();
DefaultClass2 class2 = new DefaultClass2();
}
}
// default 클래스
class DefaultClass1 {
}
class DefaultClass2 {
}
package javabasic.access.a;
public class PublicClassInnerMain {
public static void main(String[] args) {
// public, default 모두 접근 가능
PublicClass publicClass = new PublicClass();
DefaultClass1 class1 = new DefaultClass1();
DefaultClass2 class2 = new DefaultClass2();
}
}
package javabasic.access.b 패키지
package javabasic.access.b;
import javabasic.access.a.PublicClass;
public class PublicClassOuterMain {
public static void main(String[] args) {
PublicClass publicClass = new PublicClass();
// 다른 패키지 접근 불가
// DefaultClass1 class1 = new DefaultClass1();
// DefaultClass2 class2 = new DefaultClass2();
}
}