인터페이스의 모든 필드가 암시 적으로 정적이고 최종적인 이유는 무엇입니까?


100

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

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


나 자신을위한 메모 : 인터페이스의 필드가이를 구현하는 객체의 일부가되지 않기 때문에 정적입니다.
Raining

답변:


126

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

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


54
최종 필드가 상수라는 것은 반드시 사실은 아닙니다. 기본 유형에 대해서만 보장됩니다. 일반적으로 final 키워드는 메모리 위치가 변경되지 않음을 의미합니다.
Pops

8
최종 필드가 상수라고 말한 것이 아니라 상수가 최종 필드라는 것입니다. 인터페이스에 기본이 아닌 정적 최종 필드를 넣을 수 있습니다. 해당 필드의 내용이 변경 될 수 있지만 해당 필드에 대한 참조는 일정합니다.
Adriaan Koster 2012-06-15

1
@AdriaanKoster 최종 필드가 상수라고 정확히 말씀하셨습니다 . 상수 만 허용하여 상태가 적용되지 않습니다. -이 문장은 모든 최종 필드가 일정 함을 의미합니다. 당신은 당신이 사용한 단어에 대해 더 논쟁을하려고 할 수도 있지만, 분명히 당신의 진술은 오해의 소지가 있습니다.
토마스 Zato - 분석 재개 모니카

2
저의 지성이 약한 것 같지만 6 년 동안이 답변을 봤는데, 이것이 저의 최고 점수 답변 이었지만, 저는 여전히 그 발언을 이해하지 못합니다. 잘못된 것을 볼 수 없으므로 다른 문구를 제안하십시오.
Adriaan Koster

인터페이스를 상태 비 저장으로 만드는 것이 자바 디자이너의 의도 였을 수 있지만 인스턴스 필드가 수정 가능한 클래스가 될 수 있기 때문에 실패했습니다. 실패했다는 사실을 인정하는 대신 static final, const자바에서 얻을 수있는 것처럼 실제 (실제 C / C ++)에 가까운 인스턴스 필드를 강제로 선택합니다 . 불행히도 이것은 암시 적이며 비전문가에게 혼란을 줄 수 있습니다. (난 그냥 그들이 것을 깨달았다 static내가 의도하지 않은 행동을 관찰하기 때문에 나는 그들이 것을 배웠습니다. final이 대답에서만.)
하지 - 한 - 사용자

27

존재 이유 final

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

존재 이유 static

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


18

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

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

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

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

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


9

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

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

그냥 내 생각.


NawMan, "필드는 정적이어야합니다 ..."에 대한 설명은별로 의미가 없습니다. 그러나 당신은 "필드는 최종적이어야한다 ..."에 대해 매우 옳았다
peakit

1
필드가 마지막이어야하는 이유에 대해 그가 옳다고 생각하지 않습니다. 다른 구현자가 필드를 변경하도록 허용하는 것은 문제가되지 않습니다. 그렇지 않으면 상속이 문제가되기 때문입니다. Adriaan이 말했듯이 필드는 최종적이어야합니다. 왜냐하면 인터페이스는 상태 비 추적이어야하기 때문입니다. 상태가있는 인터페이스는 기본적으로 추상 클래스 여야합니다.
Axelle Ziegler

그렇지 public static않은 필드가 있으면 finalfindbugs가 (올바르게!) 불평합니다.
Tom Hawtin-tackline 2010 년

2

필자는 필드가 최종적이어야한다는 요구 사항이 지나치게 제한적이고 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";
    ...
}

당신은 필드가 최종적인 것보다 정적이라는 것에 대해 더 많이 불평하는 것 같습니다.
Daniel Yankowsky 2014-06-25

0

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

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


-1

static:

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

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

final:

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.