W C ++ oznaczenie funkcji const
składowej oznacza, że może być wywoływana w const
instancjach. Java nie ma odpowiednika tego. Na przykład:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Wartości można przypisać jednorazowo, później tylko w Javie, np .:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
jest legalne w Javie, ale nie w C ++, podczas gdy:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
Zarówno w Javie, jak i C ++ zmiennymi składowymi mogą być odpowiednio final
/ const
. Muszą one otrzymać wartość do czasu zakończenia tworzenia instancji klasy.
W Javie muszą być ustawione przed zakończeniem pracy konstruktora, można to osiągnąć na dwa sposoby:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
W C ++ będziesz musiał użyć list inicjalizacyjnych, aby nadać const
członkom wartość:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
W Java final może być używany do oznaczania rzeczy jako niepodlegających zastąpieniu. C ++ (przed C ++ 11) tego nie robi. Na przykład:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Ale w C ++:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
to jest w porządku, ponieważ semantyka oznaczania funkcji składowej const
jest inna. (Możesz również przeciążać , mając tylko const
na jednej z funkcji składowych. (Zwróć również uwagę, że C ++ 11 umożliwia oznaczanie funkcji składowych jako ostateczne, zobacz sekcję Aktualizacja C ++ 11)
Aktualizacja C ++ 11:
C ++ 11 w rzeczywistości pozwala na oznaczanie zarówno klas, jak i funkcji składowych jako final
, z identyczną semantyką dla tej samej funkcji w Javie, na przykład w Javie:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Można teraz dokładnie zapisać w C ++ 11 jako:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
Musiałem skompilować ten przykład z wersją wstępną G ++ 4.7. Zauważ, że nie zastępuje const
to w tym przypadku, ale raczej go rozszerza, zapewniając zachowanie podobne do Java, którego nie widziano z najbliższym odpowiednikiem słowa kluczowego C ++. Więc jeśli chcesz, aby funkcja członkowska była jednocześnie final
i const
zrobiłbyś:
class Bar {
public:
virtual void foo() const final;
};
(Kolejność const
i final
tutaj jest wymagana).
Wcześniej nie było bezpośredniego odpowiednika const
funkcji składowych, chociaż uczynienie funkcji innymi niż- virtual
byłoby potencjalną opcją, aczkolwiek bez powodowania błędu w czasie kompilacji.
Podobnie Java:
public final class Bar {
}
public class Error extends Bar {
}
staje się w C ++ 11:
class Bar final {
};
class Error : public Bar {
};
(Wcześniej private
konstruktory były prawdopodobnie najbliższe tego, co można było uzyskać w C ++)
Co ciekawe, w celu zachowania wstecznej kompatybilności z kodem sprzed wersji C ++ 11 w zwykły sposób final
nie jest słowem kluczowym. (Weź trywialny, legalny przykład C ++ 98, struct final;
aby zobaczyć, dlaczego uczynienie go słowem kluczowym spowodowałoby uszkodzenie kodu)
final int a; a = 10; a = 11;
tak nie jest (jest to celemfinal
jako modyfikator zmiennej). Ponadto końcowe elementy składowe klasy można ustawić tylko w czasie deklaracji lub raz w konstruktorze .final
dekorator funkcji składowej właśnie w tym celu. VC ++ 2005, 2008 i 2010 już to zaimplementowano, używając kontekstowego słowa kluczowegosealed
zamiastfinal
.W Javie ostatnie słowo kluczowe może być użyte do czterech rzeczy:
Jedna ważna rzecz: ostateczna zmienna składowa Java musi być ustawiona dokładnie raz! Na przykład w konstruktorze, deklaracji pola lub inicjalizatorze. (Ale nie można ustawić końcowej zmiennej składowej w metodzie).
Innym skutkiem ostatecznej zmiany składowej zmiennej jest model pamięci, który jest ważny, jeśli pracujesz w środowisku wątkowym.
źródło
const
Obiekt może tylko wywołaćconst
metody i jest powszechnie uważany za niezmienne.final
Obiekt nie może być ustawiony do nowego obiektu, ale to nie jest niezmienna - nie ma nic zatrzymując kogoś z wywoływania żadnychset
metod.Java nie ma własnego sposobu deklarowania niezmienności obiektów; musisz sam zaprojektować klasę jako niezmienną.
Gdy zmienna jest typem pierwotnym,
final
/const
działa tak samo.źródło
Java final jest odpowiednikiem C ++ const na pierwotnych typach wartości.
W przypadku typów referencyjnych Java słowo kluczowe final jest równoważne wskaźnikowi do stałej ... tj
źródło
Masz już tutaj kilka świetnych odpowiedzi, ale jedną kwestię, która wydawała się warta dodania:
const
w C ++ jest powszechnie używana, aby zapobiec zmianie stanu obiektów przez inne części programu. Jak już wspomniano,final
w Javie nie można tego zrobić (z wyjątkiem prymitywów) - po prostu zapobiega to zmianie odniesienia na inny obiekt. Ale jeśli używasz aCollection
, możesz zapobiec zmianom w swoich obiektach, używając metody statycznejZwraca to
Collection
odniesienie, które daje dostęp do odczytu elementów, ale zgłasza wyjątek, jeśli podejmowane są próby modyfikacji, dzięki czemu jest trochę jakconst
w C ++źródło
Java
final
działa tylko na prymitywnych typach i referencjach, nigdy na samych instancjach obiektów, gdzie słowo kluczowe const działa na czymkolwiek.Porównanie
const list<int> melist;
zfinal List<Integer> melist;
pierwszą uniemożliwia modyfikację listy, natomiast ta druga tylko uniemożliwia przypisanie nowej listy domelist
.źródło
Oprócz posiadania pewnych i subtelnych właściwości wielowątkowości , zadeklarowane zmienne
final
nie muszą być inicjowane przy deklaracji!ie Dotyczy to języka Java:
Nie byłoby to poprawne, gdyby zostało napisane w C ++
const
.źródło
Według Wikipedii :
źródło
Domyślam się, że mówi się „z grubsza”, ponieważ znaczenie
const
w C ++ komplikuje się, gdy mówisz o wskaźnikach, tj. Wskaźnikach stałych vs. wskaźnikach do obiektów stałych. Ponieważ w Javiefinal
nie ma „wyraźnych” wskaźników, nie ma tych problemów.źródło
Pozwólcie, że wyjaśnię, co zrozumiałem, na przykładzie instrukcji switch / case.
Wartości w każdej instrukcji case muszą być stałymi wartościami czasu kompilacji o tym samym typie danych, co wartość przełącznika.
zadeklaruj coś takiego jak poniżej (w swojej metodzie jako instancje lokalne lub w swojej klasie jako zmienną statyczną (dodaj do niej statyczną) lub zmienną instancji.
i
Ten kod nie będzie się kompilował, jeśli
color1
jest zmienną klasy / instancji, a nie zmienną lokalną. Skompiluje się, jeślicolor1
zostanie zdefiniowany jako statyczny wynik końcowy (wtedy stanie się statyczną zmienną końcową).Jeśli się nie skompiluje, pojawi się następujący błąd
źródło
słowo kluczowe „const” oznacza, że zmienna jest zapisana w pamięci ROM (z mikroprocesorem). w komputerze, twoja zmienna jest zapisywana w obszarze RAM dla kodu asemblera (RAM tylko do odczytu). oznacza to, że zmienna nie znajduje się w zapisywalnej pamięci RAM, w tym: pamięć statyczna, pamięć stosu i pamięć sterty.
słowo kluczowe „final” oznacza, że zmienna jest zapisywana w zapisywalnej pamięci RAM, ale kompilator zwraca uwagę, że zmienna zmienia się tylko raz.
Myślę, że „const” ma słabą wydajność, więc Java go nie używa.
źródło