튜토리얼 C ++ 프로그래머를위한 자바 그 (강조는 내 자신의) 말한다 :
final 키워드 는 C ++의 const와 거의 같습니다.
이 문맥에서 "거의"는 무엇을 의미합니까? 그들은 정확히 동일하지 않습니까?
차이점이 있다면 무엇입니까?
튜토리얼 C ++ 프로그래머를위한 자바 그 (강조는 내 자신의) 말한다 :
final 키워드 는 C ++의 const와 거의 같습니다.
이 문맥에서 "거의"는 무엇을 의미합니까? 그들은 정확히 동일하지 않습니까?
차이점이 있다면 무엇입니까?
답변:
C ++ 표시에서 멤버 함수 const
는 const
인스턴스에서 호출 될 수 있음을 의미합니다 . Java에는 이와 동등한 것이 없습니다. 예 :
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
값은 나중에 Java에서만 한 번만 지정할 수 있습니다.
public class Foo {
void bar() {
final int a;
a = 10;
}
}
Java에서는 합법적이지만 C ++에서는 합법적이지 않습니다.
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Java와 C ++에서 멤버 변수는 각각 final
/ 일 수 있습니다 const
. 클래스 인스턴스 생성이 완료 될 때까지 값을 제공해야합니다.
Java에서는 생성자가 완료되기 전에 설정해야하며, 다음 두 가지 방법 중 하나로 수행 할 수 있습니다.
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
C ++에서는 const
멤버쉽에 값 을 제공하기 위해 초기화 목록을 사용해야 합니다.
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
Java에서는 final을 사용하여 무시할 수없는 것으로 표시 할 수 있습니다. C ++ (pre-C ++ 11)은이 작업을 수행하지 않습니다. 예 :
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
그러나 C ++에서 :
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
멤버 함수를 표시하는 의미가 다르기 때문에 이것은 const
좋습니다. 멤버 함수 중 하나만 사용하여 오버로드 할 수도 const
있습니다 (C ++ 11에서는 멤버 함수를 최종으로 표시 할 수 있습니다 (C ++ 11 업데이트 섹션 참조).)
C ++ 11을 사용하면 final
Java와 같은 Java의 동일한 기능에 대해 동일한 의미 로 클래스와 멤버 함수를 모두로 표시 할 수 있습니다 .
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
이제 C ++ 11에서 다음과 같이 정확하게 작성할 수 있습니다.
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
이 예제는 G ++ 4.7의 시험판으로 컴파일해야했습니다. const
이것은이 경우를 대체 하는 것이 아니라 가장 근접한 C ++ 키워드로는 보이지 않는 Java와 유사한 동작을 제공하여 기능을 보강한다는 점에 유의하십시오. 따라서 멤버 함수를 모두 원한다면 다음 final
과 같이 const
하십시오.
class Bar {
public:
virtual void foo() const final;
};
( const
및 final
여기 의 순서 가 필요합니다).
이전에는 const
멤버 함수 와 직접적으로 동등한 기능이 없었지만 virtual
컴파일 타임에 오류를 발생시키지 않으면 서 함수를 비 만드는 것은 잠재적 인 옵션 일 수 있습니다.
마찬가지로 자바 :
public final class Bar {
}
public class Error extends Bar {
}
C ++ 11이됩니다.
class Bar final {
};
class Error : public Bar {
};
(이전에는 private
생성자가 C ++에서 가장 근접했을 것입니다)
흥미롭게도 C ++ 11 이전 코드와의 호환성을 유지하기 위해 일반적인 방식으로 키워드 final
가 아닙니다 . (사소하고 합법적 인 C ++ 98 예제 struct final;
를 통해 키워드로 만드는 것이 코드를 깨뜨리는 이유를 확인하십시오)
final int a; a = 10; a = 11;
않다는 것을 언급 할 가치가 final
있습니다. .
final
이 정확한 목적을 위해 멤버 함수 데코레이터를 추가합니다 . VC ++ 2005 년, 2008 년, 및 2010 년 이미 문맥 키워드 사용이 구현 sealed
보다는를 final
.
Java에서는 최종 키워드를 다음 네 가지 용도로 사용할 수 있습니다.
한 가지 중요한 것은 : Java 최종 멤버 변수 는 정확히 한 번 설정 해야합니다 ! 예를 들어 생성자, 필드 선언 또는 초기화 프로그램에서. 그러나 메소드에서 최종 멤버 변수를 설정할 수는 없습니다.
멤버 변수를 final로 만드는 또 다른 결과는 메모리 모델과 관련이 있으며, 이는 스레드 환경에서 작업하는 경우 중요합니다.
const
객체는 호출 할 수있는 const
방법을 일반적으로 불변의 것으로 간주됩니다.
const Person* person = myself;
person = otherPerson; //Valid... unless we declared it const Person* const!
person->setAge(20); //Invalid, assuming setAge isn't a const method (it shouldn't be)
final
객체는 새로운 객체로 설정할 수 없습니다, 그러나 그것은 불변하지 않습니다 수 있습니다 - 모든 전화에서 누군가를 중지 아무것도 없다 set
방법.
final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Java는 객체를 불변으로 선언하는 고유의 방법이 없습니다. 클래스를 변경할 수없는 것으로 디자인해야합니다.
변수가 기본 유형 인 경우 final
/ const
동일하게 작동합니다.
const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
여기에 이미 훌륭한 답변이 있지만 추가 할 가치가있는 한 가지 점이 있습니다 const
.C ++에서는 일반적으로 프로그램의 다른 부분이 객체의 상태를 변경하지 못하게합니다. 지적했듯이, final
자바에서는 이것을 할 수 없습니다 (원시적 제외)- 참조 가 다른 객체로 변경되는 것을 막습니다 . 그러나 Collection
를 사용하는 경우 정적 메소드를 사용하여 객체 변경을 방지 할 수 있습니다
Collection.unmodifiableCollection( myCollection )
이것은 Collection
요소에 대한 읽기 액세스를 제공 하는 참조를 반환 하지만 수정이 시도되면 예외를 throw하여 const
C ++에서 와 비슷하게 만듭니다.
특정한 미묘한 멀티 스레딩 속성 을 갖는 것 외에도 선언 된 변수는 선언시 final
초기화 할 필요가 없습니다!
즉, 이것은 자바에서 유효합니다 :
// declare the variable
final int foo;
{
// do something...
// and then initialize the variable
foo = ...;
}
C ++로 작성된 경우에는 유효하지 않습니다 const
.
Wikipedia 에 따르면 :
switch / case 문의 예를 통해 이해 한 내용을 설명하겠습니다.
각 경우 명령문의 값은 스위치 값과 동일한 데이터 유형의 컴파일 타임 상수 값이어야합니다.
아래에서 (로컬 인스턴스로 메소드에서 또는 클래스에서 정적 변수로 정적 추가) 인스턴스 변수를 선언하십시오.
final String color1 = "Red";
과
static final String color2 = "Green";
switch (myColor) { // myColor is of data type String
case color1:
//do something here with Red
break;
case color2:
//do something with Green
break;
}
이 코드는 color1
클래스 / 인스턴스 변수이고 로컬 변수 가 아닌 경우 컴파일 되지 않습니다. color1
정적 최종으로 정의 된 경우 컴파일 된 다음 정적 최종 변수가됩니다.
컴파일하지 않으면 다음과 같은 오류가 발생합니다
error: constant string expression required
키워드 "const"는 변수가 ROM에 저장되어 있음을 의미합니다 (마이크로 프로세서 포함). 컴퓨터에서 변수는 어셈블리 코드의 RAM 영역에 저장됩니다 (RAM 만 읽기). 변수가 쓰기 가능한 RAM에 없다는 것을 의미합니다 : 정적 메모리, 스택 메모리 및 힙 메모리.
키워드 "final"은 변수가 쓰기 가능한 RAM에 저장된다는 것을 의미하지만 변수가 한 번만 변경된다는 것을 컴파일러에 알 수 있습니다.
//in java language you can use:
static final int i =10;
i =11; //error is showed here by compiler
//the same in C++ the same as follows
int i =10;
const int &iFinal = i;
iFinal = 11; //error is showed here by compiler the same as above
"const"는 성능이 좋지 않기 때문에 Java는 사용하지 않습니다.