The only difference between the final and const keyword is that final is a runtime-constant, which in turn means that its value can be assigned at runtime instead of the compile-time that we had for the const keyword.
Developers don't use the const keyword in Java to mark fields as constants. Instead, they daisy chain the keywords static final in Java to create an arguably global variable with an unchangeable value.
Constant is the concept, the property of the variable. final is the java keyword to declare a constant variable.
const means its initial value is must be fixed, can not be a dynamic value; final means its initial value is must be fixed but can be a dynamic value, equal to the var with a fixed value.
In C++ marking a member function const
means it may be called on const
instances. Java does not have an equivalent to this. E.g.:
class Foo {
public:
void bar();
void foo() const;
};
void test(const Foo& i) {
i.foo(); //fine
i.bar(); //error
}
Values can be assigned, once, later in Java only e.g.:
public class Foo {
void bar() {
final int a;
a = 10;
}
}
is legal in Java, but not C++ whereas:
public class Foo {
void bar() {
final int a;
a = 10;
a = 11; // Not legal, even in Java: a has already been assigned a value.
}
}
In both Java and C++ member variables may be final
/const
respectively. These need to be given a value by the time an instance of the class is finished being constructed.
In Java they must be set before the constructor has finished, this can be achieved in one of two ways:
public class Foo {
private final int a;
private final int b = 11;
public Foo() {
a = 10;
}
}
In C++ you will need to use initialisation lists to give const
members a value:
class Foo {
const int a;
public:
Foo() : a(10) {
// Assignment here with = would not be legal
}
};
In Java final can be used to mark things as non-overridable. C++ (pre-C++11) does not do this. E.g.:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
But in C++:
class Bar {
public:
virtual void foo() const {
}
};
class Error: public Bar {
public:
// Fine in C++
virtual void foo() const {
}
};
this is fine, because the semantics of marking a member function const
are different. (You could also overload by only having the const
on one of the member functions. (Note also that C++11 allows member functions to be marked final, see the C++11 update section)
C++11 does in fact allow you to mark both classes and member functions as final
, with identical semantics to the same feature in Java, for example in Java:
public class Bar {
public final void foo() {
}
}
public class Error extends Bar {
// Error in java, can't override
public void foo() {
}
}
Can now be exactly written in C++11 as:
class Bar {
public:
virtual void foo() final;
};
class Error : public Bar {
public:
virtual void foo() final;
};
I had to compile this example with a pre-release of G++ 4.7. Note that this does not replace const
in this case, but rather augments it, providing the Java-like behaviour that wasn't seen with the closest equivalent C++ keyword. So if you wanted a member function to be both final
and const
you would do:
class Bar {
public:
virtual void foo() const final;
};
(The order of const
and final
here is required).
Previously there wasn't a direct equivalent of const
member functions although making functions non-virtual
would be a potential option albeit without causing an error at compile time.
Likewise the Java:
public final class Bar {
}
public class Error extends Bar {
}
becomes in C++11:
class Bar final {
};
class Error : public Bar {
};
(Previously private
constructors was probably the closest you could get to this in C++)
Interestingly, in order to maintain backwards compatibility with pre-C++11 code final
isn't a keyword in the usual way. (Take the trivial, legal C++98 example struct final;
to see why making it a keyword would break code)
A const
object can only call const
methods, and is generally considered immutable.
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)
A final
object cannot be set to a new object, but it is not immutable - there is nothing stopping someone from calling any set
methods.
final Person person = myself;
person = otherPerson; //Invalid
person.setAge(20); //Valid!
Java has no inherent way of declaring objects immutable; you need to design the class as immutable yourself.
When the variable is a primitive type, final
/const
work the same.
const int a = 10; //C++
final int a = 10; //Java
a = 11; //Invalid in both languages
In Java the final keyword can be used for four things:
One important thing is: A Java final member variable must be set exactly once! For example, in a constructor, field declaration, or intializer. (But you cannot set a final member variable in a method).
Another consequence of making a member variable final relates to the memory model, which is important if you work in a threaded environment.
Java final is equivalent to C++ const on primitive value types.
With Java reference types, the final keyword is equivalent to a const pointer... i.e.
//java
final int finalInt = 5;
final MyObject finalReference = new MyObject();
//C++
const int constInt = 5;
MyObject * const constPointer = new MyObject();
You have some great answers here already, but one point that seemed worth adding: const
in C++ is commonly used to prevent other parts of the program changing the state of objects. As has been pointed out, final
in java can't do this (except for primitives) - it just prevents the reference from being changed to a different object. But if you are using a Collection
, you can prevent changes to your objects by using the static method
Collection.unmodifiableCollection( myCollection )
This returns a Collection
reference that gives read-access to the elements, but throws an exception if modifications are attempted, making it a bit like const
in C++
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With