인터페이스의 모든 필드가 암시 적으로 정적이고 최종적인 이유는 무엇입니까? 없지만 왜 final(암시 적으로) 존재합니까? 자바 디자이너가 인터페이스의

인터페이스에 정의 된 모든 필드가 암시 적으로 staticfinal. 필드를 유지한다는 생각은 static인터페이스의 객체를 가질 수 없지만 왜 final(암시 적으로) 존재합니까?

자바 디자이너가 인터페이스의 필드를 만들어 갔다 이유 중 하나는 알고 staticfinal?



답변

인터페이스는 상호 작용 계약 만 지정하고 구현 세부 정보는 지정하지 않기 때문에 동작이나 상태를 가질 수 없습니다. ‘행동 없음’은 메서드 / 생성자 본문 또는 정적 / 인스턴스 초기화 블록을 허용하지 않음으로써 강제됩니다. ‘상태 없음’은 정적 최종 필드 만 허용하여 적용됩니다. 따라서 클래스는 상태 (정적 상태)를 가질 수 있지만 인스턴스 상태는 인터페이스에 의해 유추되지 않습니다.

BTW : Java의 상수는 정적 최종 필드로 정의됩니다 (일반적으로 이름은 UPPER_CASE_AND_UNDERSCORES를 사용함).


답변

존재 이유 final

최종적으로 정의되지 않은 모든 구현은 필드 값을 변경할 수 있습니다. 그런 다음 그들은 구현의 일부가 될 것입니다. 인터페이스는 구현이없는 순수한 사양입니다.

존재 이유 static

정적 인 경우 개체 나 개체의 런타임 유형이 아닌 인터페이스에 속합니다.


답변

여기에 몇 가지 요점이 있습니다.

인터페이스의 필드가 암시 적으로 static final이라고해서 컴파일 타임 상수이거나 변경 불가능한 것도 아닙니다. 예를 들어 정의 할 수 있습니다.

interface I {
  String TOKEN = SomeOtherClass.heavyComputation();
  JButton BAD_IDEA = new JButton("hello");
}

(주석 정의 내에서이 작업을 수행 하면 위의 내용이 실제로 정적 초기화 프로그램으로 컴파일된다는 사실과 관련하여 javac혼동 할 수 있습니다 .)

또한 이러한 제한의 이유는 기술적 인 것보다 문체 적이며 많은 사람들이이 제한이 완화되기를 원합니다 .


답변

필드는 추상적 일 수 없기 때문에 정적이어야합니다 (메소드처럼). 추상적 일 수 없기 때문에 구현자는 필드의 다른 구현을 논리적으로 제공 할 수 없습니다.

필드는 여러 구현자가 액세스 할 수 있으므로 변경 가능할 수 있으므로 (동기화로) 문제가 될 수 있기 때문에 필드는 최종적이어야합니다. 또한 다시 구현 (숨김)되는 것을 방지합니다.

그냥 내 생각.


답변

필자는 필드가 최종적이어야한다는 요구 사항이 지나치게 제한적이고 Java 언어 디자이너의 실수라고 생각합니다. 인터페이스 유형의 객체에 대한 작업을 수행하는 데 필요한 구현에서 상수를 설정해야하는 경우, 예를 들어 트리 처리와 같은 경우가 있습니다. 구현 클래스에서 코드 경로를 선택하는 것은 어려운 일입니다. 내가 사용하는 해결 방법은 인터페이스 함수를 정의하고 리터럴을 반환하여 구현하는 것입니다.

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";
    ...
}


답변

사양, 계약 … 필드 액세스를위한 기계 명령어는 객체 주소와 필드 오프셋을 사용합니다. 클래스는 많은 인터페이스를 구현할 수 있으므로이 인터페이스를 확장하는 모든 클래스에서 동일한 오프셋을 갖도록 비 최종 인터페이스 필드를 만들 수있는 방법이 없습니다. 따라서 필드 액세스를위한 다른 메커니즘이 구현되어야합니다. 하나가 아닌 두 개의 메모리 액세스 (필드 오프셋 가져 오기, 필드 값 가져 오기)와 가상 필드 테이블의 종류 (가상 메소드 테이블의 아날로그)를 유지합니다. 기존 항목 (방법)을 통해 쉽게 시뮬레이션 할 수있는 기능을 위해 jvm을 복잡하게 만들고 싶지는 않은 것 같습니다.

스칼라에서는 인터페이스에 필드를 가질 수 있지만 내부적으로는 위에서 설명한대로 (메서드로) 구현됩니다.


답변

static:

아무것도 (가변 또는 방법) static자바 같이 호출 될 수 Classname.variablename또는 Classname.methodname직접. 개체 이름을 사용해서 만 호출 할 필요는 없습니다.

인터페이스에서는 객체를 선언 할 수 없으며 객체 static이름 없이도 클래스 이름만으로 변수를 호출 할 수 있습니다.

final:

하위 클래스에서 재정의 할 수 없으므로 변수에 대한 상수 값을 유지하는 데 도움이됩니다.