IT

자바`최종`방법 : 그것은 무엇을 약속합니까?

lottoking 2020. 6. 27. 10:39
반응형

자바`최종`방법 : 그것은 무엇을 약속합니까?


Java 클래스 final에서이 메소드가 대체되지 않을 수 있음을 표시 하기 위해 메소드를로 정의 할 수 있습니다 .

public class Thingy {
    public Thingy() { ... }
    public int operationA() {...}
    /** this method does @return That and is final. */
    public final int getThat() { ...}
}

분명합니다. 우연한 재정의 또는 성능 저하로부터 보호하는 데 유용 할 수 있습니다. 그러나 그것은 제 질문이 아닙니다.

내 질문은 : OOP 관점 final에서 클래스 디자이너 가 메소드를 정의 함으로써이 메소드가 항상 설명 된대로 또는 암시 적으로 작동 할 것이라고 약속 했습니다. 그러나 종종 방법이 수행하는 것이 더 복잡하고 속성을 제공하는 것보다 복잡한 경우 클래스 작성자의 영향을 벗어날 수 있습니다 .

구문상의 제약은 나에게 분명하지만 OOP 의미의 의미는 무엇입니까? 되어 final대부분의 클래스 저자에 의해 이러한 의미에서 올바르게 사용?

방법은 어떤 종류의 "계약"을 final약속합니까?


언급 한 바와 같이 finalJava 메소드와 함께 사용하여 메소드를 대체 (객체 범위)하거나 숨길 수 없음 (정적)을 표시합니다. 이를 통해 원래 개발자는 서브 클래스로 변경할 수없는 기능을 작성할 수 있으며 이것이 제공하는 모든 보증입니다.

즉, 방법이 비공개 필드 / 방법과 같은 다른 사용자 정의 가능한 구성 요소에 의존하는 경우 최종 방법의 기능은 여전히 ​​사용자 정의 할 수 있습니다. 이것은 (다형성과 함께) 부분적인 커스터마이징이 가능하지만 좋습니다.

다음을 포함하여 무언가를 사용자 정의 할 수 없도록하는 데는 여러 가지 이유가 있습니다.

  • 성능 -일부 컴파일러는 작업, 특히 부작용이없는 작업을 분석하고 최적화 할 수 있습니다.

  • 캡슐화 된 데이터를 얻 습니다. 생성시 속성이 설정되어 절대로 변경되어서는 안되는 불변 개체를 살펴보십시오. 또는 해당 속성에서 파생 된 계산 된 값입니다. 좋은 예는 Java String클래스입니다.

  • 신뢰성 및 계약은 - 객체는 프리미티브 (구성된다 int, char, double, 등) 및 / 또는 기타 객체. 이러한 구성 요소에 적용 가능한 모든 작업이 더 큰 개체에서 사용될 때 적용 가능하거나 논리적이어야하는 것은 아닙니다. final수정자를 사용한 메소드를 사용하여이를 확인할 수 있습니다. 카운터 클래스가 좋은 예입니다.


public class Counter {
    private int counter = 0;

    public final int count() {
        return counter++;
    }

    public final int reset() {
        return (counter = 0);
    }
}

public final int count()메소드가 아닌 경우 final다음과 같이 할 수 있습니다.

Counter c = new Counter() {   
    public int count() {
        super.count();   
        return super.count();   
    } 
}

c.count(); // now count 2

또는 이와 같은 것 :

Counter c = new Counter() {
    public int count() {
        int lastCount = 0;
        for (int i = super.count(); --i >= 0; ) {
            lastCount = super.count();
        }

        return lastCount;
    }
}

c.count(); // Now double count

최종 방법은 어떤 종류의 "계약"을 약속합니까?

Look at it the other way, any non final method makes the implicit guarantee that you can override it with your own implementation and the class will still work as expected. When you can't guarantee that your class supports overwriting a method you should make it final.


First of all, you can mark non-abstract classes final as well as fields and methods. This way whole class can't be subclassed. So, behavior of class will be fixed.

I agree that marking methods final don't guarantee that their behavior will be the same in subclasses if these methods are calling non-final methods. If behavior is indeed need to be fixed, this has to be achieved by convention and careful design. And don't forget to notion this in javadoc!(java documentation)

Last but not the least, final keyword has very important role in Java Memory Model (JMM). It's guaranteed by JMM that to achieve visibility of final fields you don't need proper synchronization. E.g.:

class A implements Runnable {
  final String caption = "Some caption";                           

  void run() {
    // no need to synchronize here to see proper value of final field..
    System.out.println(caption);
  }
}  

I'm not sure you can make any assertions about the use of "final" and how that impacts the overall design contract of the software. You are guaranteed that no developer can override this method and void its contract that way. But on the other hand, the final method may rely on class or instance variables whose values are set by subclasses, and can call other class methods that are overridden. So final is at most a very weak guarantee.


No, it's not outside the influence of the class author. You can't override it in your derived class, therefore it will do what the base class author intended.

http://download.oracle.com/javase/tutorial/java/IandI/final.html

Worth noting is the part where it suggests that methods called from constructors should be final.

참고URL : https://stackoverflow.com/questions/5547663/java-final-method-what-does-it-promise

반응형