programing

효과적인 최종 vs 최종 - 다른 동작

goodsources 2023. 2. 6. 23:27
반응형

효과적인 최종 vs 최종 - 다른 동작

지금까지 나는 최종과 최종이 거의 동등하다고 생각했고, JLS가 실제 동작에서 동일하지 않더라도 비슷하게 취급할 것이라고 생각했다.그러다가 나는 다음과 같은 시나리오를 발견했다.

final int a = 97;
System.out.println(true ? a : 'c'); // outputs a

// versus

int a = 97;
System.out.println(true ? a : 'c'); // outputs 97

분명히 JLS는 이 두 가지 사이에 중요한 차이를 만들며 나는 왜 그런지 잘 모르겠다.

나는 다른 글을 읽는다.

그렇게 상세하게 설명하지는 않습니다.결국, 더 넓은 수준에서 그들은 거의 동등하게 보인다.하지만 더 깊이 파고들면, 그들은 분명히 다르다.

이 동작의 원인은 무엇입니까?누구나 이 동작을 설명하는 JLS 정의를 제공할 수 있습니까?


편집: 다른 관련 시나리오를 찾았습니다.

final String a = "a";
System.out.println(a + "b" == "ab"); // outputs true

// versus

String a = "a";
System.out.println(a + "b" == "ab"); // outputs false

따라서 문자열 인터닝도 여기서 다르게 동작합니다(이 스니펫을 실제 코드로 사용하고 싶지 않습니다.다양한 동작이 궁금할 뿐입니다).

우선, 우리는 지역 변수에 대해서만 이야기하고 있습니다.사실상 final은 필드에 적용되지 않습니다.이것은 중요합니다.의 의미론에서final필드는 매우 구별되며 컴파일러의 최적화와 메모리 모델의 약속에 따라 달라집니다.최종 필드의 의미에 대해서는 $17.5.1을 참조해 주세요.

레벨에서 ★★★★★★★★★★★★★★★★★★★★★★」final ★★★★★★★★★★★★★★★★★」effectively final로컬 변수의 경우 실제로 동일합니다.그러나 JLS는 이와 같은 특수한 상황에서 실제로 광범위한 영향을 미치는 두 가지를 명확히 구분한다.


전제

JLS™4.12.4부터의 개요final★★★★

상수 변수는finalprimitive type 또는 type String의 변수로서 상수 표현식15.29)으로 초기화됩니다.변수가 상수 변수인지 아닌지는 클래스 초기화(1212.4.1), 이진 호환성(1313.1), 도달 가능성(1414.22) 및 확정 할당(1616.1.1)과 관련하여 영향을 미칠 수 있습니다.

★★int입니다.a상수 변수입니다.

같은 에서 「」, 「」, 「」에 대해 설명합니다.effectively final:

최종으로 선언되지 않은 특정 변수는 사실상 최종으로 간주됩니다.

이렇게 다른 에서는 그서이이른, 른른른른른른, so른른른른른른 so so so so so so so so so so so so,a는 최종 변수가 아니라 사실상 최종 변수이기 때문에 상수 변수로 간주되지 않습니다.


행동

이것으로 구별을 할 수 있게 되었습니다.무슨 일이 일어나고 있는지, 왜 출력이 다른지를 조사합니다.

조건 the the the the the the the the 를 사용하고 .? :그래서 우리는 그것의 정의를 확인해야 합니다.JLS 15.25부터:

두 번째 및 세 번째 피연산자 식에 따라 분류되는 조건식에는 부울 조건식, 수치 조건식참조 조건식의 3종류가 있습니다.

이 예에서는 JLS 15.25.2의 수치 조건식에 대해 설명합니다.

수치 조건식의 유형은 다음과 같이 결정됩니다.

그리고 그것이 두 사건이 다르게 분류되는 부분이다.

사실상 최종적인

''effectively final는 다음 규칙에 따라 일치합니다.

그 이외의 경우는, 제2 오퍼랜드와 제3 오퍼랜드에 일반 수치 승격(55.6)이 적용되어 조건식의 타입은 제2 오퍼랜드와 제3 오퍼랜드의 승격 타입이 됩니다.

은 마치 것과 입니다.5 + 'd' discriptions.int + char 「」가 됩니다.intJLS®5.6」을 참조해 주세요.

숫자 승진은 숫자 컨텍스트에서 모든 식의 승격 유형을 결정합니다.각 식을 승격형으로 변환할 수 있도록 승격형을 선택하고, 산술 연산의 경우 승격형 값에 대해 연산을 정의합니다.숫자 컨텍스트에서의 식 순서는 숫자 승격에 유의하지 않습니다.규칙은 다음과 같습니다.

[...]

다음으로, 확대 원시 변환(55.1.2)과 축소 원시 변환(15.1.3)이 일부 표현에 적용되며, 즉 축소 원시 변환(55.1.3)에 적용한다.

숫자 선택 컨텍스트에서는 다음 규칙이 적용됩니다.

이 " " "인 "int상수 표현식이 아닌 경우(premissed 15.29), 승격된 유형은 다음과 같습니다.int int로의 원시적인 전환이 확대되다int.

So everything is promoted to 그래서 모든 것이 로 승격된다.int as ~하듯이a is an 는 입니다.int이미.이미. That explains the output of 그것이 그 결과를 설명해 준다.97.

최종

전 버 의 the)final이 규칙에 따라 변수는 다음과 일치합니다.변수는 다음 규칙에 의해 일치합니다.

오퍼랜드 중 하나가 유형인 경우T어디에Tbyte,short, 또는char다른 피연산자는 type의 상수 표현식(timeout15.29)입니다.int그 가치는 활자로 나타낼 수 있다T조건식의 타입은 다음과 같습니다.T.

최종 변수a종류int(왜냐하면 그것은) 상수표현이다.final)는 다음과 같이 나타낼 수 있습니다.char따라서 결과는 유형입니다.char이것으로 출력은 종료됩니다.a.


문자열 예시

이 있는 는 같은 인 「코어 차이.final되며, 는 상수식/변수로 됩니다.effectively final렇지않않 않않않다다

Java에서는 문자열 인터닝은 상수 표현식을 기반으로 합니다.

"a" + "b" + "c" == "abc"

true(실제 코드에서 이 구성을 사용하는 경우도 있습니다.

JLS®3.10.5」를 참조해 주세요.

또한 문자열 리터럴은 항상 클래스 String의 동일한 인스턴스를 참조합니다.이는 스트링 리터럴(또는 보다 일반적으로 상수 표현의 값인 스트링('15.29))이 고유한 인스턴스를 공유하기 위해 메서드를 사용하여 "interned"되기 때문입니다.String.intern(제12.5절).

주로 리터럴을 말하고 있기 때문에 간과하기 쉽지만, 실제로는 일정한 표현에도 적용됩니다.

또 다른 측면은 변수가 메서드 본문에서 최종으로 선언된 경우 매개 변수로 전달된 최종 변수와 다른 동작을 갖는 것입니다.

public void testFinalParameters(final String a, final String b) {
  System.out.println(a + b == "ab");
}

...
testFinalParameters("a", "b"); // Prints false

하는 동안에

public void testFinalVariable() {
   final String a = "a";
   final String b = "b";
   System.out.println(a + b == "ab");  // Prints true
}

...
testFinalVariable();

가 '사용하는 것이 좋다'는 있기 때문입니다.final String a = "a"a ""를 ."a"을 매기다a ★★★★★★★★★★★★★★★★★」"a"문제없이 교환할 수 있습니다. 방법으로, ''이면, ''a되어 있지 않다final '어디로 하다'라고 정의되어 있습니다.final, 이 은 실행은 final이다).a파라미터) 컴파일러는 사용하기 전에 아무것도 알지 못합니다.따라서 연결은 실행 시 실행되며 intern 풀을 사용하지 않고 새 문자열이 생성됩니다.


기본적으로, 컴파일러가 변수가 상수라는 것을 알고 있는 경우, 변수를 사용하는 것과 동일하게 사용할 수 있습니다.

변수가 final로 정의되지 않은 경우(또는 final이지만 실행 시 값이 정의되어 있는 경우), 값이 상수와 동일하고 값이 변경되지 않은 경우에도 컴파일러가 상수로 처리할 이유가 없습니다.

언급URL : https://stackoverflow.com/questions/63738711/effectively-final-vs-final-different-behavior

반응형