인터페이스의 모든 필드가 암시 적으로 정적이고 최종적으로 인가는 이유는 무엇입니까?
-
19-09-2019 - |
문제
인터페이스에 정의 된 모든 필드가 암시 적으로 왜 static
그리고 final
. 필드를 유지한다는 아이디어 static
인터페이스의 객체를 가질 수 없지만 왜 final
(암시 적으로)?
누구든지 Java 디자이너가 인터페이스에서 필드를 만드는 이유를 알고 있습니다. static
그리고 final
?
해결책
인터페이스는 동작이나 상태를 가질 수 없습니다. 상호 작용 계약 만 지정하고 구현 세부 사항이 없기 때문입니다. 방법/생성자 본체 또는 정적/인스턴스 초기화 블록을 허용하지 않음으로써 동작이 시행되지 않습니다. 정적 최종 필드 만 허용함으로써 상태가 시행되지 않으며,이 클래스는 상태 (정적 상태)를 가질 수 있지만 인스턴스 상태는 인터페이스에 의해 추론되지 않습니다.
BTW : Java의 상수는 정적 최종 필드에 의해 정의됩니다 (컨벤션에 따라 이름은 Topper_Case_and_underscores를 사용합니다).
다른 팁
존재의 이유 final
모든 구현은 필드가 최종으로 정의되지 않은 경우 필드 값을 변경할 수 있습니다. 그러면 그들은 구현의 일부가 될 것입니다. 인터페이스는 구현이없는 순수한 사양입니다.
존재의 이유 static
그들이 정적 인 경우, 객체 나 객체의 런타임 유형이 아닌 인터페이스에 속합니다.
여기에는 몇 가지 포인트가 있습니다.
인터페이스의 필드가 암시 적으로 정적 최종이기 때문에 컴파일 타임 상수 또는 불변이어야한다는 의미는 아닙니다. 예를 들어 정의 할 수 있습니다
interface I { String TOKEN = SomeOtherClass.heavyComputation(); JButton BAD_IDEA = new JButton("hello"); }
(주석 정의 내 에서이 작업을 수행 할 수 있다고 조심하십시오. Javac을 혼동하십시오, 위의 것이 실제로 정적 이니셜 라이저로 컴파일한다는 사실과 관련이 있습니다.)
또한,이 제한의 이유는 기술보다 더 스타일이므로 많은 사람들이 편안한 것을 보는 것을 좋아합니다.
필드는 추상적이 될 수 없기 때문에 정적이어야합니다 (방법과 마찬가지로). 추상적이 될 수 없기 때문에 구현자는 필드의 다른 구현을 논리적으로 제공 할 수 없습니다.
많은 다른 구현자가 필드를 액세스 할 수 있기 때문에 필드는 최종적으로 이루어져야한다고 생각합니다. 또한 재 구현을 피하기 위해 (숨겨진).
단지 내 생각.
나는 필드가 최종적으로 최종적이며 Java Language Designers의 실수로 최종적이라는 요구 사항을 고려합니다. 인터페이스 유형의 객체에서 작업을 수행하는 데 필요한 구현에서 상수를 설정 해야하는 경우가 있습니다. 구현 클래스에서 코드 경로를 선택하는 것은 kludge입니다. 내가 사용하는 해결 방법은 인터페이스 함수를 정의하고 문자를 반환하여 구현하는 것입니다.
public interface iMine {
String __ImplementationConstant();
...
}
public class AClass implements iMine {
public String __ImplementationConstant(){
return "AClass value for the Implementation Constant";
}
...
}
public class BClass implements iMine {
public String __ImplementationConstant(){
return "BClass value for the Implementation Constant";
}
...
}
그러나이 구문을 사용하기 위해 더 간단하고 명확하며 비정상적인 구현이 덜 발생합니다.
public interface iMine {
String __ImplementationConstant;
...
}
public class AClass implements iMine {
public static String __ImplementationConstant =
"AClass value for the Implementation Constant";
...
}
public class BClass implements iMine {
public static String __ImplementationConstant =
"BClass value for the Implementation Constant";
...
}
사양, 계약 ... 필드 액세스 용 머신 명령어는 객체 주소와 필드 오프셋을 사용합니다. 클래스는 많은 인터페이스를 구현할 수 있으므로이 인터페이스를 확장하는 모든 클래스에서 동일한 오프셋을 가질 수 있도록 비 결절 인터페이스 필드를 만들 수있는 방법이 없습니다. 따라서 필드 액세스를위한 다른 메커니즘이 구현되어야합니다. 하나의 가상 필드 테이블을 유지하는 하나의 가상 필드 테이블 (가상 메소드 테이블의 아날로그) 대신 두 가지 메모리 액세스 (필드 오프셋, 필드 값 GET)를 구현해야합니다. 기존 재료 (메소드)를 통해 쉽게 시뮬레이션 할 수있는 기능에 대해 JVM을 복잡하게하고 싶지 않은 것 같습니다.
Scala에서는 인터페이스에 필드를 가질 수 있지만 내부적으로 위에서 설명한대로 구현됩니다 (방법).
static
:
무엇이든 (가변 또는 방법)입니다 static
Java에서는 AS를 호출 할 수 있습니다 Classname.variablename
또는 Classname.methodname
또는 직접. 객체 이름을 사용 하여만 호출하는 것은 의무적이지 않습니다.
인터페이스에서는 객체를 선언 할 수 없습니다 static
객체 이름없이 클래스 이름을 통해 변수를 호출 할 수 있습니다.
final
:
서브 클래스에서는 무시할 수 없으므로 변수의 일정한 값을 유지하는 데 도움이됩니다.