답변:
기본 가시성은 "package-private"(명시 적으로 사용할 수는 없지만)로 알려져 있습니다. 즉, 클래스가 속한 동일한 패키지 내에서 필드에 액세스 할 수 있습니다.
mdma가 지적했듯이, 기본값이 "public"인 인터페이스 멤버에게는 사실이 아닙니다.
기본 지정자는 컨텍스트에 따라 다릅니다.
클래스 및 인터페이스 선언의 경우 기본값은 패키지 전용입니다. 이것은 보호 된 것과 개인용 사이에 속하며 동일한 패키지 액세스의 클래스 만 허용합니다. (protected는 이와 비슷하지만 패키지 외부의 하위 클래스에 대한 액세스도 허용합니다.)
class MyClass // package private
{
int field; // package private field
void calc() { // package private method
}
}
인터페이스 멤버 (필드 및 메서드)의 경우 기본 액세스는 공용입니다. 그러나 인터페이스 선언 자체의 기본값은 private 패키지입니다.
interface MyInterface // package private
{
int field1; // static final public
void method1(); // public abstract
}
그런 다음 선언이 있으면
public interface MyInterface2 extends MyInterface
{
}
MyInterface2를 사용하는 클래스는 MyInterface 자체의 선언을 볼 수 없더라도 공용이므로 super 인터페이스에서 field1 및 method1을 볼 수 있습니다.
/* pp */
)는 기본 액세스에 편리한 이름 일뿐 입니다. JLS 이름이 아닙니다.
그것이 무엇인지에 달려 있습니다.
최상위 유형 (즉, 다른 유형 내에서 선언되지 않은 클래스, 열거 형, 인터페이스 및 주석 유형)은 기본적으로 패키지 전용 입니다. ( JLS §6.6.1 )
클래스에서 모든 멤버 (필드, 메서드 및 중첩 된 형식 선언을 의미 함)와 생성자는 기본적으로 패키지 전용 입니다. ( JLS §6.6.1 )
열거 형에서 생성자는 기본적으로 비공개 입니다. 실제로 enum contructor 는 private 이어야 하며 public 또는 protected로 지정하는 것은 오류입니다. 열거 형 상수는 항상 public 이며 액세스 지정자를 허용하지 않습니다. 열거 형의 다른 멤버는 기본적으로 패키지 전용 입니다. ( JLS §8.9 )
인터페이스 및 주석 유형에서 모든 멤버 (다시 말하면 필드, 메서드 및 중첩 유형 선언을 의미 함)는 기본적으로 공용 입니다. 실제로 인터페이스 및 주석 유형의 멤버는 공용 이어야 하며이를 개인 또는 보호로 지정하는 것은 오류입니다. ( JLS §9.3 ~ 9.5 )
로컬 클래스는 메서드, 생성자 또는 이니셜 라이저 블록 내에 선언 된 명명 된 클래스입니다. 이들은 선언 된 .. 블록 으로 범위{
}
가 지정되며 액세스 지정자를 허용하지 않습니다. ( JLS §14.3 ) 리플렉션을 사용하면 다른 곳에서 로컬 클래스를 인스턴스화 할 수 있으며 해당 세부 사항이 JLS에 있는지 확실하지 않지만 package-private 입니다.
익명 클래스는 new
표현식에서 직접 클래스 본문을 지정하는 데 사용 되는 사용자 정의 클래스입니다 . ( JLS §15.9.5 ) 해당 구문은 액세스 지정자를 허용하지 않습니다. 리플렉션을 사용하면 다른 곳에서 익명 클래스를 인스턴스화 할 수 있으며 해당 세부 사항이 JLS에 있는지 확실하지 않지만 둘 다 및 생성 된 생성자는 package-private 입니다.
인스턴스 및 정적 이니셜 라이저 블록에는 언어 수준 ( JLS §8.6 및 8.7 ) 에서 액세스 지정자가 없지만 정적 이니셜 라이저 블록은 이름이 지정된 메서드 <clinit>
( JVMS §2.9 ) 로 구현 되므로 메서드에는 내부적으로 일부 액세스 지정자가 있어야합니다. 16 진 편집기를 사용하여 javac 및 Eclipse의 컴파일러로 컴파일 된 클래스를 검사 한 결과 둘 다 package-private 로 메서드를 생성한다는 것을 발견했습니다 . 그러나 메서드 이름에서 및 문자가 유효하지 않고 리플렉션 메서드가 그 존재를 거부하도록 고정되어 <clinit>()
있기 때문에 언어 내에서 호출 할 수 없으므로 액세스 지정자는 액세스 권한 이 없습니다 . 이 메서드는 클래스 초기화 중에 VM에서만 호출 할 수 있습니다.<
>
인스턴스 이니셜 라이저 블록은 별도의 메서드로 컴파일되지 않습니다. 그들의 코드는 각 생성자에 복사되므로 리플렉션을 통해서도 개별적으로 액세스 할 수 없습니다.
default 는 메소드 및 변수에 대한 액세스 수정 자로 사용되는 키워드입니다.
이 액세스 수정자를 사용하면 클래스, 변수, 메서드 또는 생성자가 자신의 클래스 또는 패키지에서 액세스 할 수있게되며 액세스 수정자가없는 경우에도 설정됩니다.
Access Levels
Modifier Class Package Subclass EveryWhere
public Y Y Y Y
protected Y Y Y N
default Y Y N N
private Y N N N
인터페이스에서 기본값을 사용하면이 예제와 같은 메서드를 구현할 수 있습니다.
public interface Computer {
default void Start() {
throw new UnsupportedOperationException("Error");
}
}
그러나 8 Java 버전에서만 작동합니다.
다음은 Java를 만든 James Gosling과의 인터뷰에서 패키지 수준 가시성에 대한 인용문입니다.
Bill Venners : Java에는 4 가지 액세스 수준이 있습니다. 기본값은 패키지입니다. C ++의 사람들이 이미 알고있는 세 가지 키워드가 private, protected 및 public이기 때문에 패키지 액세스를 기본값으로 만드는 것이 편리한 지 항상 궁금해했습니다. 또는 패키지 액세스가 기본값이어야한다고 생각하는 특별한 이유가있는 경우.
James Gosling : 패키지는 일반적으로 함께 쓰여진 것들의 집합입니다. 그래서 일반적으로 두 가지 중 하나를 할 수있었습니다. 하나는 도메인을 제공하는 키워드를 항상 입력하도록 강요하는 것입니다. 아니면 기본값을 가질 수도 있습니다. 그리고 문제는 무엇이 합리적인 기본값을 만드는가입니다. 그리고 나는 가장 위험한 것을 추구하는 경향이 있습니다.
따라서 공개는 기본값을 설정하는 데 정말 나쁜 일이었습니다. 사람들이 실제로 private 메서드를 자주 작성하지 않기 때문에 Private은 아마도 기본값을 만드는 것이 좋지 않았을 것입니다. 보호 된 것과 똑같습니다. 그리고 제가 가지고있는 많은 코드를 살펴보면서 합리적으로 안전한 가장 일반적인 것은 패키지에 있다고 결정했습니다. 그리고 C ++에는 패키지 개념이 없기 때문에 키워드가 없었습니다.
하지만 친구 개념보다는 좋아했습니다. 친구와 함께라면 모든 친구가 누구인지 열거해야하기 때문에 패키지에 새 클래스를 추가하면 일반적으로 모든 그 패키지의 클래스와 친구들을 업데이트했습니다. 나는 항상 엉덩이에 완전한 고통을 느꼈습니다.
그러나 친구 목록 자체는 일종의 버전 문제를 일으 킵니다. 그래서 친절한 수업이라는 개념이있었습니다. 그리고 제가 이것을 기본값으로 만든 좋은 점은-문제를 해결할 것이므로 키워드는 무엇이어야합니까?
한동안 친근한 키워드가있었습니다. 그러나 나머지는 모두 "P"로 시작하기 때문에 "PH"로 "친절"했습니다. 그러나 그것은 아마도 하루 동안 만 거기에있었습니다.
Java 8default
키워드 사용 업데이트 : 다른 많은 사람들이 언급했듯이 기본 가시성 (키워드 없음)
이 필드는 클래스가 속한 동일한 패키지 내에서 액세스 할 수 있습니다.
인터페이스가 키워드로 레이블이 지정되었을 때 구현을 제공 할 수 있도록하는 새로운 Java 8 기능 ( Default Methods ) 과 혼동하지 마십시오 default
.
참조 : 액세스 수정 자
JAVA에는 해당 패키지 내에서만 해당 엔티티의 직접 인스턴스 생성을 허용하는 "default"라는 액세스 수정자가 있습니다.
다음은 유용한 링크입니다.
우선 자바에는 "액세스 지정자"와 같은 용어가 없습니다. 모든 것을 "Modifiers"라고 불러야합니다. final, static, synchronised, volatile ....이 수정 자로 호출된다는 것을 알고 있듯이 Public, private, protected, default, abstract도 modifiers로 호출해야합니다. 기본값은 물리적 존재는 없지만 수정자가 배치되지 않은 수정자는 기본 수정 자로 취급되어야합니다.
이를 정당화하기 위해 한 가지 예를 들면 다음과 같습니다.
public class Simple{
public static void main(String args[]){
System.out.println("Hello Java");
}
}
출력은 다음과 같습니다. Hello Java
이제 public을 private으로 변경하고 어떤 컴파일러 오류가 발생하는지 확인하십시오. "Modifier private is not allowed here"라는 메시지가 표시됩니다. 어떤 결론은 누군가가 틀릴 수 있거나 일부 튜토리얼이 틀릴 수 있지만 컴파일러는 틀릴 수 없다는 것입니다. 그래서 우리는 자바에 용어 접근 지정자가 없다고 말할 수 있습니다.