[java] 인터페이스 메소드의 최종 인수-요점은 무엇입니까?

Java에서는 final인터페이스 메소드에서 인수 를 정의 하고 구현 클래스에서 인수 를 정의 하지 않는 것이 합법적입니다 .

public interface Foo {
    public void foo(int bar, final int baz);
}

public class FooImpl implements Foo {

    @Override
    public void foo(final int bar, int baz) {
        ...
    }
}

위의 예에서 barbaz반대의 보유 final인터페이스 VS 클래스의 정의.

같은 방식으로 final한 클래스 메소드가 다른 클래스 메소드를 다른 클래스 메소드로 확장 할 때 제한이 적용 abstract되지 않습니다.

반면 final클래스 방법 본체 내부의 실제 값을 가지고, 특정 포인트가 어떤 final인터페이스 방법 매개 변수는?



답변

요점이없는 것 같습니다. Java 언어 사양 4.12.4 에 따르면 :

변수 final을 선언하면 값이 변경되지 않으며 프로그래밍 오류를 피할 수 있다는 유용한 문서로 사용할 수 있습니다.

그러나 final메서드 매개 변수 의 수정자는 재정의 된 메서드의 서명을 일치 시키는 규칙에 언급되어 있지 않으며 구현 본문 내에서만 호출자에게 영향을 미치지 않습니다. 또한 주석에서 Robin이 언급 한 것처럼 final메소드 매개 변수 의 수정자는 생성 된 바이트 코드에 영향을 미치지 않습니다. (이것은 다른 용도로는 적용되지 않습니다 final.)


답변

일부 IDE는 서브 클래스에 구현 메소드를 삽입 할 때 추상 / 인터페이스 메소드의 서명을 복사합니다.

컴파일러와 차이가 있다고 생각하지 않습니다.

편집 : 과거에는 이것이 사실이라고 생각하지만 현재 IDE가 더 이상 이것을하지 않는다고 생각합니다.


답변

메소드 매개 변수의 최종 주석은 항상 호출자에게 절대로 메소드 구현과 관련이 없습니다. 따라서 인터페이스 메소드 시그니처에 사용할 이유가 없습니다. 모든 메서드 시그니처에서 최종 메서드 매개 변수가 필요한 동일한 일관된 코딩 표준을 따르지 않는 한. 그러면 그렇게 할 수있어서 좋습니다.


답변

업데이트 : 아래의 원래 답변은 질문을 완전히 이해하지 않고 작성되었으므로 질문을 직접 해결하지는 못하지만 키워드 :)의 일반적인 사용법을 이해하려는 사람들에게는 유익해야합니다 final.

질문에 대해서는 아래에서 내 의견을 인용하고 싶습니다.

나는 당신이 자신의 구현에서 최종적인 것인지 아닌지를 자유롭게 결정할 수 있도록 논쟁의 최종성을 구현해서는 안된다고 생각합니다 .

그러나 그렇습니다 final. 인터페이스에서 선언 할 수는 있지만 구현에서 최종적이지 않은 것은 다소 이상하게 들립니다 . 다음 중 하나에 해당하면 더 의미가있을 것입니다.

ㅏ. final인터페이스 (추상) 메소드 인수에 키워드가 허용되지 않았지만 (구현에 사용할 수 있음)
b. final인터페이스에서 와 같이 인수를 선언하면 final구현 에서 인수를 선언 해야하지만 (최종이 아닌 경우에는 적용되지 않음)


메소드 서명이 final매개 변수 를 가질 수있는 두 가지 이유를 생각할 수 있습니다 : Beans and Objects ( 실제로 그들은 같은 이유이지만 약간 다른 컨텍스트입니다. )

사물:

public static void main(String[] args) {
    StringBuilder cookingPot = new StringBuilder("Water ");
    addVegetables(cookingPot);
    addChicken(cookingPot);
    System.out.println(cookingPot.toString());
    // ^--- OUTPUT IS: Water Carrot Broccoli Chicken ChickenBroth 
    //      We forgot to add cauliflower. It went into the wrong pot.
}

private static void addVegetables(StringBuilder cookingPot) {
    cookingPot.append("Carrot ");
    cookingPot.append("Broccoli ");
    cookingPot = new StringBuilder(cookingPot.toString());
    //   ^--- Assignment allowed...
    cookingPot.append("Cauliflower ");
}

private static void addChicken(final StringBuilder cookingPot) {
    cookingPot.append("Chicken ");
    //cookingPot = new StringBuilder(cookingPot.toString());
    //     ^---- COMPILATION ERROR! It is final.
    cookingPot.append("ChickenBroth ");
}

final키워드는 우리가 실수로 새 생성되지 않습니다 보장 현지 우리가 그렇게 할 시도 할 때 컴파일 오류를 보여줌으로써 요리 냄비를. 이를 통해 닭 국물이 addChicken방법이 얻은 원래 요리 냄비에 추가됩니다 . addVegetables콜리 플라워를 잃어버린 곳 과 원래의 냄비 대신 새로운 지역 요리 냄비에 추가했기 때문에 이것을 비교하십시오 .

Beans :
객체와 동일한 개념입니다 (위 그림 참조) . 콩은 본질적 Object으로 Java에 있습니다. 그러나 Bean (JavaBeans)은 정의 된 관련 데이터 콜렉션을 저장하고 전달하는 편리한 방법으로 다양한 애플리케이션에서 사용됩니다. addVegetables새로운 요리 냄비를 만들어 StringBuilder콜리 플라워로 버려 요리 과정을 망칠 수있는 것처럼 요리 냄비 JavaBean으로도 같은 작업을 수행 할 수 있습니다 .


답변

나는 그것이 세부 사항인지 아닌지에 대한 세부 사항 일 수 있다고 생각합니다. 구현 세부 사항입니다.

(공개로 인터페이스에서 메소드 / 멤버를 선언하는 것과 같습니다.)


답변