Why is there no Constant feature in Java?
Asked Answered
H

9

158

I was trying to identify the reason behind constants in Java I have learned that Java allows us to declare constants by using final keyword.

My question is why didn't Java introduce a Constant (const) feature. Since many people say it has come from C++, in C++ we have const keyword.

Please share your thoughts.

Hilariahilario answered 29/4, 2010 at 8:19 Comment(1)
There is a const keyword, but there is no underlying feature. Corrected your title and tags accordingly.Vivyan
E
157

Every time I go from heavy C++ coding to Java, it takes me a little while to adapt to the lack of const-correctness in Java. This usage of const in C++ is much different than just declaring constant variables, if you didn't know. Essentially, it ensures that an object is immutable when accessed through a special kind of pointer called a const-pointer When in Java, in places where I'd normally want to return a const-pointer, I instead return a reference with an interface type containing only methods that shouldn't have side effects. Unfortunately, this isn't enforced by the langauge.

Wikipedia offers the following information on the subject:

Interestingly, the Java language specification regards const as a reserved keyword — i.e., one that cannot be used as variable identifier — but assigns no semantics to it. It is thought that the reservation of the keyword occurred to allow for an extension of the Java language to include C++-style const methods and pointer to const type. The enhancement request ticket in the Java Community Process for implementing const correctness in Java was closed in 2005, implying that const correctness will probably never find its way into the official Java specification.

Enjoy answered 29/4, 2010 at 8:49 Comment(6)
Java's final is similar, though.Givens
No it isn't. final method for example work completely different from C++ const methods.Sharpie
@Givens The final keyword on properties or variables just ensures that a property or variable is only assigned to once. One could still alter the state of this object by, for example, calling some method with side effects. final is somewhat similair to stack allocation of C++ in terms of refering to an object rather than a pointer, but that's all it is. This is ofcourse in addition to what dom0 already said.Tinaret
final in Java seems to work like C++ const for value types, but more like a C++ non-const T& for reference typesQuadrillion
final is a schizophrenic keyword. While it prevents reassignment, it's also used to expose variables to closures. I might want to prevent reassignment but not expose those variables, but there's no way to do it. It's a rather poorly thought out language feature in my opinion.Southpaw
final creates runtime constants while const will create compile time constants. In other words if we declare a field final, it can be changed inside the constructor, if declared static final it can be changed inside a static initializer block but if you want that the field shouldn't allowed be changed after declaration, then const will be needed which is currently not available.Sadden
S
90

What does const mean
First, realize that the semantics of a "const" keyword means different things to different people:

  • read-only reference - Java final semantics - reference variable itself cannot be reassigned to point to another instance (memory location), but the instance itself is modifiable
  • readable-only reference - C const pointer/reference semantics - means this reference cannot be used to modify the instance (e.g. cannot assign to instance variables, cannot invoke mutable methods) - affects the reference variable only, so a non-const reference pointing to the same instance could modify the instance
  • immutable object - means the instance itself cannot be modified - applies to instance, so any non-const reference would not be allowed or could not be used to modify the instance
  • some combination of the the above?
  • others?

Why or Why Not const
Second, if you really want to dig into some of the "pro" vs "con" arguments, see the discussion under this request for enhancement (RFE) "bug". This RFE requests a "readable-only reference"-type "const" feature. Opened in 1999 and then closed/rejected by Sun in 2005, the "const" topic was vigorously debated:

https://bugs.java.com/bugdatabase/view_bug?bug_id=4211070

While there are a lot of good arguments on both sides, some of the oft-cited (but not necessarily compelling or clear-cut) reasons against const include:

  • may have confusing semantics that may be misused and/or abused (see the What does const mean above)
  • may duplicate capability otherwise available (e.g. designing an immutable class, using an immutable interface)
  • may be feature creep, leading to a need for other semantic changes such as support for passing objects by value

Before anyone tries to debate me about whether these are good or bad reasons, note that these are not my reasons. They are simply the "gist" of some of the reasons I gleaned from skimming the RFE discussion. I don't necessarily agree with them myself - I'm simply trying to cite why some people (not me) may feel a const keyword may not be a good idea. Personally, I'd love more "const" semantics to be introduced to the language in an unambiguous manner.

Sack answered 29/4, 2010 at 9:44 Comment(2)
+1 just for the second part of your answer. Many many keywords have non-trivial semantics. Is volatile so simple to understand? Or final? Meh.Boanerges
OTOH, Java was designed to use as few of those non-trivial features as possible. And I'm not saying that they achieved that goal (or that Java hasn't drifted away from that goal). But excluding it for that reason may still have had merit. That there are other complicated things is all the more reason not to introduce more (or you'd end up with the D language).Fredrick
S
7

const in C++ does not mean that a value is a constant.

const in C++ implies that the client of a contract undertakes not to alter its value.

Whether the value of a const expression changes becomes more evident if you are in an environment which supports thread based concurrency.

As Java was designed from the start to support thread and lock concurrency, it didn't add to confusion by overloading the term to have the semantics that final has.

eg:

#include <iostream>

int main ()
{
    volatile const int x = 42;

    std::cout << x << std::endl;

    *const_cast<int*>(&x) = 7;

    std::cout << x << std::endl;

    return 0;
}

outputs 42 then 7.

Although x marked as const, as a non-const alias is created, x is not a constant. Not every compiler requires volatile for this behaviour (though every compiler is permitted to inline the constant)

With more complicated systems you get const/non-const aliases without use of const_cast, so getting into the habit of thinking that const means something won't change becomes more and more dangerous. const merely means that your code can't change it without a cast, not that the value is constant.

Shawana answered 29/4, 2010 at 8:38 Comment(14)
const int x = 42; - x is a constantMilord
@Neil I think he's talking about objectsMarital
@andy Works the same for objects.Milord
@Neil What I meant was: when Pete wrote that const does not mean a value is constant, my understanding was that he was only talking about primitive types. To explain further (and I appreciate that you know this stuff): For a const non-object variable (say an int), the compiler enforces the contract. If I declare it const then it can't be changed. For a object I have to declare as const any member functions that modify the object's internal state. If I don't then its possible to have a const instance of that class that is (internally) mutable. That was my understanding of what he wrote.Marital
@Neil If you have one object or variable aliased by both const and non-const pointers, then the value of the const alias can be changed by the non-const alias. Therefore const does not mean a value is constant. It means that the client of a value is constrained not to mutate it. In your example there is no alias, so all users are under the same constraint. This is not the case in general. const effects the clients, not the value - it says you can't change it, not that it won't change.Shawana
I was thinking about the objectsHilariahilario
Const-correctness is about what the programmer should do, not what they can do. I think you all seem to have got that point. Just wanted to add a couple of cents that could be of interest to the causal reader: Design patterns like the immutable interface and immutable object is another way (beatable with cast and reflection) to mimic const in Java. "True" const can be done with SealedObject, alas it destroys the use case of our object.Leannleanna
One should note that the outcome of your program is undefined. const_cast is not there to change const variables, it is there to pass const variables to APIs that are not const correct, but also do not modify the value. I think the habit of thinking that something const won't change is a good one because if they do change, that means your program contains hacks that might break at any time depending on the compiler used.Wonderland
@Wonderland in the example it shows you can use a hack to create a non-const alias. But not all non-const aliases are hacks, for example passing c and c+1 to strncpy will violate any assumption in strncpy that the source won't change .Shawana
@PeteKirkham Precisely, and because of that passing overlapping memory to strncpy() is a hack, too -- it lands you in undefined territory: "The behavior of strncpy is undefined if the strings overlap" (GNU C Library, similar warnings in any other C library). Only memmove() is an exception and needs special sauce in the library implementation to protect against aliasing.Wonderland
Modifying a born-to-constant value is undefined behavior. Your disk may be already formatted.Kempf
@ZheYang it's an illustration. More realistic issues tends to come up where you have one thread mutating an object which was passed into another as a const reference, and that thread assumes it won't change, but that would mean much longer demonstration code.Shawana
@Milord is quite wrong to claim that const works the same for objects and for fundamental integer types. That's just not true. See the discussion in this SO question for example.Boanerges
The claim that it outputs 42 then 7 is wrong; the behavior is undefined. The key is that x was declared const (so, for example, it could be placed in read-only memory). In this example, it would be valid for the compiler to completely ignore the assignment and print 42 twice. If x had been declared without const and been passed as a const-reference to another function, the const_cast would be legal.Hasson
O
7

This is a bit of an old question, but I thought I would contribute my 2 cents anyway since this thread came up in conversation today.

This doesn't exactly answer why is there no const? but how to make your classes immutable. (Unfortunately I have not enough reputation yet to post as a comment to the accepted answer)

The way to guarantee immutability on an object is to design your classes more carefully to be immutable. This requires a bit more care than a mutable class.

This goes back to Josh Bloch's Effective Java Item 15 - Minimize Mutability. If you haven't read the book, pick up a copy and read it over a few times I guarantee it will up your figurative "java game".

In item 15 Bloch suggest that you should limit the mutability of classes to ensure the object's state.

To quote the book directly:

An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is provided when it is created and is fixed for the lifetime of the object. The Java platform libraries contain many immutable classes, including String, the boxed primitive classes, and BigInte- ger and BigDecimal. There are many good reasons for this: Immutable classes are easier to design, implement, and use than mutable classes. They are less prone to error and are more secure.

Bloch then describes how to make your classes immutable, by following 5 simple rules:

  1. Don’t provide any methods that modify the object’s state (i.e., setters, aka mutators)
  2. Ensure that the class can’t be extended (this means declaring the class itself as final).
  3. Make all fields final.
  4. Make all fields private.
  5. Ensure exclusive access to any mutable components. (by making defensive copies of the objects)

For more details I highly recommend picking up a copy of the book.

Off answered 7/6, 2016 at 19:36 Comment(1)
const in C++ is MUCH more flexible than full-scale immutability. In a sense, 'const' can be seen as 'immutable within this particular context'. Example: I have a class that isn't immutable, BUT I want to ensure that it is not modified via certain public APIs. Making an interface (and returning it for that public API) as suggested by Gunslinger47 achieves the same thing in Java, but boy - it IS ugly (and so - it is ignored by most of Java developers, leading to significant unnecessary mess)...Montano
O
4

The C++ semantics of const are very different from Java final. If the designers had used const it would have been unnecessarily confusing.

The fact that const is a reserved word suggests that the designers had ideas for implementing const, but they have since decided against it; see this closed bug. The stated reasons include that adding support for C++ style const would cause compatibility problems.

Outplay answered 29/4, 2010 at 8:34 Comment(0)
T
0

According to one of the text book that I have refered tells that, "const is a Java keyword but it is not being used now to create constants. so, you need to use final keyword"

Tolmach answered 15/10, 2023 at 12:42 Comment(1)
You are right, but this information is already abundantly clear from the other answers. In its brevity it may only confuse others.Chaddy
E
-1

You can use static final to create something that works similar to Const, I have used this in the past.

protected static final int cOTHER = 0;
protected static final int cRPM = 1;
protected static final int cSPEED = 2;
protected static final int cTPS = 3;
protected int DataItemEnum = 0;

public static final int INVALID_PIN = -1;
public static final int LED_PIN = 0;
Extraterritorial answered 13/4, 2013 at 16:24 Comment(4)
Downvoted for rumor-based optimization because I heard a rumor that this is an ineffective strategy.Presentment
I removed the rumor from the answer. you can still use static final int to create const style code.Extraterritorial
Ok, I have removed my downvote. Maybe some of the other downvotes are about the switch statement (what does it have to do with the rest of your example?)Presentment
in the switch statement I used the cRPM as if it was a const. quite right, considering the above. so yes i have removed the switch.Extraterritorial
G
-1

There is a way to create "const" variables in Java, but only for specific classes. Just define a class with final properties and subclass it. Then use the base class where you would want to use "const". Likewise, if you need to use "const" methods, add them to the base class. The compiler will not allow you to modify what it thinks is the final methods of the base class, but it will read and call methods on the subclass.

Greeneyed answered 7/3, 2016 at 2:14 Comment(2)
Can you provide some example of this, please?Endoskeleton
class MYString implements GetString { private final String aaaa; public String getString(); } class MutableString implements GetString { private String aaaa2; public String getString(); public String setString() }Greeneyed
M
-3

There would be two ways to define constants - const and static final, with the exact same semantics. Furthermore static final describes the behaviour better than const

Maomaoism answered 29/4, 2010 at 8:29 Comment(2)
@Bozho, you said better behaviour than Const, what way it is? can you share any exampleHilariahilario
well, the variable is static (not belonging to particular instance) and final - cannot be changed.Maomaoism

© 2022 - 2024 — McMap. All rights reserved.