C #에서 Java의 final에 해당하는 것은 무엇입니까?


답변:


861

final키워드는 자바에서 여러 가지 용도가있다. 사용되는 컨텍스트에 따라 C # 의 sealedreadonly키워드에 모두 해당합니다 .

클래스

서브 클래 싱을 방지하려면 (정의 된 클래스의 상속) :

자바

public final class MyFinalClass {...}

씨#

public sealed class MyFinalClass {...}

행동 양식

virtual메소드의 오버라이드를 방지하십시오 .

자바

public class MyClass
{
    public final void myFinalMethod() {...}
}

씨#

public class MyClass : MyBaseClass
{
    public sealed override void MyFinalMethod() {...}
}

Joachim Sauer가 지적한 것처럼, 두 언어의 주목할만한 차이점은 Java는 기본적으로 모든 비 정적 메소드를으로 virtual표시하고 C #은을 표시 한다는 것 sealed입니다. 따라서 기본 클래스에 sealed명시 적으로 표시된 메서드의 재정의를 더 이상 중지하지 않으려면 C # 에서 키워드 만 사용해야합니다 virtual.

변수

변수를 한 번만 할당하려면 :

자바

public final double pi = 3.14; // essentially a constant

씨#

public readonly double pi = 3.14; // essentially a constant

참고로, readonly키워드 의 효과 constreadonly표현식이 compile-time이 아닌 런타임시 평가 되므로 임의의 표현식을 허용 한다는 점에서 키워드 의 효과 와 다릅니다 .


15
Java의 모든 비 정적 메소드는 기본적으로 가상이라고 덧붙입니다. 따라서 C #에서는 초기 정의에서 가상을 간단하게 제외 할 수 있지만 "최종"을 사용하여 Java에서 서브 클래스가이를 재정의하지 않도록해야합니다.
Joachim Sauer

166
좋은 답변-자바에서 "최종"을 한 번 더 사용하면 지역 변수 또는 메소드 매개 변수에 다시 할당을 막을 수 있습니다. 이에 상응하는 c # 직접적인 것은 없습니다.
serg10

17
readonly멤버 변수 생성자에서 수정할 있습니다. pastebin.com/AzqzYGiA
재귀

8
또한 참고 : 자바에서 마지막으로 멤버 변수를 선언하면되지 모든 생성자 양수인 C #을하는 동안 모든 코드 경로의 값은 단지 읽기 전용 멤버 변수와 그 시나리오에 경고 발행하는 경우, 컴파일러는, 불평
Mene

1
@NickolayKondratyev : 예, 다른 클래스에서 서브 클래 싱해야한다는 점에서 내 예는 암시 적이었습니다. 인터페이스가 실제로 필요하지 않습니다. 그것은 불필요하지만 그렇지 않으면 옳게 보입니다.
Noldorin

180

상황에 따라 다릅니다.


1
실제로 선언 될 때 최종 변수를 할당 할 필요는 없습니다. 'final'은 변수가 참조되기 전에 일부 코드 경로로 변수를 지정해야하며 코드 경로에서 변수를 두 번 이상 지정할 수 없음을 의미합니다. 이는 인스턴스 변수에 적용되는데, 이는 사실상 생성자가 변수를 명시 적으로 할당해야 함을 의미합니다.
Jay

31
+ For a final local variable or method parameter, there's no direct C# equivalent큰 차이가 있습니다.
Daniel B. Chapman

1
당신이 경우 인스턴스화 , const를 로컬 변수를 사용할 수 있습니다. 물론 때문에 동일하지의 최종 수 있습니다 별도로 선언하고 초기화 (그래서 다른 값을 가지고), 그러나 다만 경우에 당신은 몰랐 ...
Griknok

3
const값 유형에만 사용할 수 있습니다. 내가 아는 한 로컬 참조 유형에 효과적인 상수를 만들 수있는 방법이 없습니다.
jocull 2016 년

2
@jocull 문자열이 유일한 예외입니다.
Raimund Krämer

46

여기서 누락 된 것은 최종 멤버 변수에 대한 명확한 할당을 보장하는 Java의 보증입니다.

최종 멤버 변수가 V 인 클래스 C의 경우 C의 모든 생성자를 통한 모든 가능한 실행 경로는 V를 정확히 한 번만 지정해야합니다. V를 지정하지 않거나 V를 두 번 이상 지정하지 않으면 오류가 발생합니다.

C #의 readonly 키워드는 그러한 보장을하지 않습니다. 컴파일러는 readonly 멤버를 할당하지 않은 채로 두거나 생성자 내에서 여러 번 할당하도록 허용하는 것 이상으로 행복합니다.

따라서 final 및 readonly (적어도 멤버 변수와 관련하여)는 동등하지 않습니다. final은 훨씬 엄격합니다.


7

언급 된 바와 같이, sealed등가 인 final방법 및 클래스는.

나머지는 복잡합니다.

  • 들어 static final필드, static readonly가능한 가장 가까운 것입니다. 정적 생성자에서 정적 필드를 초기화 할 수 있습니다. 이는 Java의 정적 초기화 기와 상당히 유사합니다. 이는 상수 (프리미티브 및 불변 객체)와 변경 가능한 객체에 대한 상수 참조 모두에 적용됩니다.

    const수정은 상수 상당히 유사하지만 정적 생성자에서 그들을 설정할 수 없습니다.

  • 생성자를 떠난 후에는 다시 할당하지 않아야하는 필드에서 readonly사용할 수 있습니다. 그것은 같지 않습니다- final생성자 또는 이니셜 라이저에서도 정확히 하나의 할당이 필요합니다.
  • final내가 아는 지역 변수에 해당 하는 C #은 없습니다 . 왜 누구에게 필요한지 궁금하다면 : if-else, switch-case 등 전에 변수를 선언 할 수 있습니다 . 최종 선언하면 최대 한 번 할당됩니다.

    일반적으로 Java 로컬 변수는 읽기 전에 한 번 이상 지정해야합니다. 값을 읽기 전에 분기가 튀어 나오지 않으면 최종 변수가 정확히 한 번 할당됩니다. 이 모든 것은 컴파일 타임에 확인됩니다. 이를 위해서는 오류에 대한 마진이 적은 잘 동작하는 코드가 필요합니다.

요약하자면 C #에는에 해당하는 값이 없습니다 final. Java에는 C #의 멋진 기능이 없지만 C #이 동등한 기능을 제공하지 못하는 곳을 Java 프로그래머로 보는 것이 나에게 상쾌합니다.


6

Java 클래스 final 및 메소드 final-> 봉인되었습니다. Java 멤버 변수 final-> 런타임 상수의 경우 읽기 전용, 컴파일 시간 상수의 const.

지역 변수 final 및 메소드 인수 final에 해당하지 않습니다.



0

봉인


8
문맥에 의존하고 설명 및 / 또는 예를 추가하기 때문에 대답의 일부만이 도움이 필요한 사람들을 위해 훨씬 더 소화하기 쉬울 것입니다.
Rune FS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.