Java'S Final Vs. C++'S Const

Java's final vs. C++'s const

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 update:

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)

Difference between final and const?

In java, making something final means that it can't be reasigned to another reference to another instance, but if it's a reference to a mutable class, the mutable values inside the class can still be modified.

For example, a final String is a constant because Strings are immutable in Java, but a final ArrayList means that you cannot assign it to another ArrayList, but you can still add and remove elements to that ArrayList

What is the difference between the const and final keywords in Dart?

There is a post on dart's website and it explains it pretty well.

Final:

"final" means single-assignment: a final variable or field must have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies variables.


Const:

"const" has a meaning that's a bit more complex and subtle in Dart. const modifies values. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determined entirely at compile time and that the object will be frozen and completely immutable.

Const objects have a couple of interesting properties and restrictions:

They must be created from data that can be calculated at compile time. A const object does not have access to anything you would need to calculate at runtime. 1 + 2 is a valid const expression, but new DateTime.now() is not.

They are deeply, transitively immutable. If you have a final field containing a collection, that collection can still be mutable. If you have a const collection, everything in it must also be const, recursively.

They are canonicalized. This is sort of like string interning: for any given const value, a single const object will be created and re-used no matter how many times the const expression(s) are evaluated.



So, what does this mean?

Const:

If the value you have is computed at runtime (new DateTime.now(), for example), you can not use a const for it. However, if the value is known at compile time (const a = 1;), then you should use const over final. There are 2 other large differences between const and final. Firstly, if you're using const inside a class, you have to declare it as static const rather than just const. Secondly, if you have a const collection, everything inside of that is in const. If you have a final collection, everything inside of that is not final.

Final:

final should be used over const if you don't know the value at compile time, and it will be calculated/grabbed at runtime. If you want an HTTP response that can't be changed, if you want to get something from a database, or if you want to read from a local file, use final. Anything that isn't known at compile time should be final over const.


With all of that being said, both const and final cannot be reassigned, but fields in a final object, as long as they aren't const or final themselves, can be reassigned (unlike const).

In Java, when do you use const instead of final?

const (and goto) is never used. It's just a reserved keyword in Java.

Note that when using const (or goto) the code doesn't even compile.

More info:

  • Why const keyword is not used in Java ?
  • Why there is no constant keyword in Java ?

Compared to C#, Java's final is similar to const or readonly

readonly, because just like in C#, you can only set final once, including within the constructor.

What is the equivalent of Java's final in C#?

The final keyword has several usages in Java. It corresponds to both the sealed and readonly keywords in C#, depending on the context in which it is used.

Classes

To prevent subclassing (inheritance from the defined class):

Java

public final class MyFinalClass {...}

C#

public sealed class MyFinalClass {...}

Methods

Prevent overriding of a virtual method.

Java

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

C#

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

As Joachim Sauer points out, a notable difference between the two languages here is that Java by default marks all non-static methods as virtual, whereas C# marks them as sealed. Hence, you only need to use the sealed keyword in C# if you want to stop further overriding of a method that has been explicitly marked virtual in the base class.

Variables

To only allow a variable to be assigned once:

Java

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

C#

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

As a side note, the effect of the readonly keyword differs from that of the const keyword in that the readonly expression is evaluated at runtime rather than compile-time, hence allowing arbitrary expressions.

Equivalent of const(C++) in Java

Basically, I want to make sure a given returned class cannot be
modified and is read only. Is that possible in Java?

Not directly, but one workaround is an immutable object.

Example -

public final Foo{

private final String s;

public Foo(String s){
this.s = s;
}

// Only provide an accessor!
public String getString(){
return s;
}
}

Java final String, C++ equivalent. Is my understanding correct?

When we say that Java String(s) are immutable, it is because a String object cannot be modified once created. Instead, you must create (and assign a reference to) a new String when you want to modify a String reference. When you mark a String variable as final you are additionally making the reference immutable.



Related Topics



Leave a reply



Submit