• Post Reply Bookmark Topic Watch Topic
  • New Topic

what makes a compile time constant?  RSS feed

 
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

While trying to go through switch case flow control instruction in java ( SCJP book by Kathy and Bert - Page 336), I have come across this line.

"Since the case argument has to be resolved at compile time, that means you can use only a constant or final variable that is assigned a literal value". The example posted is as follows.



Could somebody please explain to me what a compile time constant is?
Does the above example suggest that whenever the declaration and initialization of a primitive final variable is done in a single line, we get a compile time constant?

Also, can instance variables be compile time constants?

So if I have my class as follows



are any of the instance variables( i and k ), static variable j, and Dog variable compile time constants?

Do compile time constants have to be final if they have an explicitly declared reference ( as opposed to literals like "abc" in cases like --> g = "abc" +c; which I guess are compile time constants or aren't they?) ?

If somebody could guide me on what makes any variable a constant ( what I know is that any variable that is final is a constant as we can't change its value. Are Immutable objects constants too? Example - cached Integer Objects from pool, String objects in String pool. Would they be constants too?) and a compile time constant, it would really help me a lot.

Thanks in advance.
Chan.



 
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chan Ag wrote:Could somebody please explain to me what a compile time constant is?

A Constant Variable is a variable whose value can't change during the course of the execution of code. A Constant Variable and a compile-time Constant Variable are the same thing - the JLS makes no mention of a compile-time Constant Variable. It does make a reference to a compile-time Constant Expression, but more on that later.

The reason people call Constant Variables compile-time constants because their values can be known at compile-time, and a compiler can substitute the literal the constant refers to at any location the variable is used. Example, if I did this:

The compiler knows that val is and will always be 2, so instead of using the variable and having to look that value up at runtime, the compiler can insert the value directly into the equation:

This could be interpreted as a compile-time constant expression and evaluated at compile time instead of runtime, and be further optimized to:


Does the above example suggest that whenever the declaration and initialization of a primitive final variable is done in a single line, we get a compile time constant?

Also, can instance variables be compile time constants?

Yes, on both accounts. At least, in my reading of the JLS, there was no distinction between static and instance constants.

So if I have my class as follows



are any of the instance variables( i and k ), static variable j, and Dog variable compile time constants?

Given what you know now, what do you think?

Do compile time constants have to be final...

Yes. It does not matter what the rest of the sentence is. To be a constant, the value must not be able to change. A non-final variable can change.

Do compile time constants have to be final if they have an explicitly declared reference ( as opposed to literals like "abc" in cases like --> g = "abc" +c; which I guess are compile time constants or aren't they?) ?

It depends. If the line is: final String g = "abc" + c; then there is a possibility that g is a compile-time constant. If g is not declared final then no, there is no chance g is a compile-time constant. In the first case, if the line is final String g = "abc" + c; then g might be a compile time constant if the expression "abc" + c is a compile-time constant expression, and that would mean that c would have to be a compile-time constant itself: that is, declared like final String c = "def";. If so, then the constant express could be evaluated at compile time to "abcdef" and that literal be assigned to g.

If somebody could guide me on what makes any variable a constant ( what I know is that any variable that is final is a constant as we can't change its value. Are Immutable objects constants too?

Immutable objects aren't variables, they are objects. Only variables can be constants. You need to know the difference between the two.

Example - cached Integer Objects from pool, String objects in String pool. Would they be constants too?) and a compile time constant, it would really help me a lot.

Thanks in advance.
Chan.



 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I meant to post links to the relevant parts of the JLS:
final an constant variabls: http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.12.4
compile-time constant expressions: http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Luke wrote:
Chan Ag wrote:Does the above example suggest that whenever the declaration and initialization of a primitive final variable is done in a single line, we get a compile time constant?

Also, can instance variables be compile time constants?

Yes, on both accounts. At least, in my reading of the JLS, there was no distinction between static and instance constants.

I should amend that regarding the first question to say 'yes, when a primitive (or String) final variable is declared and initialized on a single line, it is a constant, as long as the the value it is assigned is a literal or a compile-time constant expression.
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greetings and thanks so much, Steve. That was really, really helpful. I think I understand now what a compile time constant is.

So if I have my class as follows

view plaincopy to clipboardprint?
Note: Text content in the code blocks is automatically word-wrapped
public class TestClass {

final int i;
static final int j;
final int k = 5;
Dog a;

static { j = 5;}

TestClass(){ i = 10; }

}

are any of the instance variables( i and k ), static variable j, and Dog variable compile time constants?

Given what you know now, what do you think?


For the above case, would the following be reasonable arguments?

1. i is not a compile time constant as it's value will be set only after an instance is created at run time after the constructor runs. From that point onwards this value cannot change. But at compile time, i would not be a constant as compiler cannot substitute this value in place of the variable.
2. static final variable j also would not be a compile time constant as it's value will be known when the class is loaded and after the static init block runs.
3. final variable k would be a compile time constant as it is initialized with a value that cannot change and compiler can substitute this value wherever applicable.
4. Dog variable a is not a constant as it is not final. So it cannot be a compile time constant.

Would that be correct?

Chan

 
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chan Ag wrote:Would that be correct?

You know what? You need Henry Wong (one of the posters on here), because he's produced a great distillation of exactly this subject, filtered from the JLS. If I find a link to his answer, I'll post it here.

Winston
 
Ranch Hand
Posts: 247
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
You know what? You need Henry Wong (one of the posters on here), because he's produced a great distillation of exactly this subject, filtered from the JLS. If I find a link to his answer, I'll post it here.
Winston


It's here
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chan Ag wrote:...
4. Dog variable a is not a constant as it is not final. So it cannot be a compile time constant.

Would that be correct?

That would all be correct, but if the variable a was declared as final Dog a = new Dog(); it would still not be a constant variable. Why is that?
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rameshwar Soni wrote:It's here

Cheers Rameshwar.

Winston
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks all, for your responses and suggestions. I really appreciate them.

That post by Henry Wong was indeed very helpful. Just I couldn't figure where enums would fit in this discussion of compile time constants.

So if I had an enum like say..



Would variable a in the case of ( final Dog a = Dog.PEMPEM; ) not be a compile time constant? If we consider that a switch expression can also be anything that evaluates to an enum, wouldn't it also imply that enum references are also compile time constants. But the JLS ( I've read only a few things that pointed me to compile time constants and enums ) refers to enum variables as just enum constants and does not mention enums in its reference of compile time constants. So would that mean enum variables are not compile time constants?

Also, when I coded two classes Temp and TestEnums as follows.



After compiling both classes and enum and running TestEnums, it printed PEMPEM.
When I recompiled Temp after changing Dog variable a of Temp class to
static final Dog a = Dog.SISSY;
and executed TestEnums without recompiling TestEnums, it printed "SISSY".


C:\Users\Chan\Desktop\Java Practice Programs>javac Dog.java

C:\Users\Chan\Desktop\Java Practice Programs>javac Temp.java

C:\Users\Chanl\Desktop\Java Practice Programs>javac TestEnums.java

C:\Users\Chan\Desktop\Java Practice Programs>java TestEnums
PEMPEM

C:\Users\Chan\Desktop\Java Practice Programs>javac Temp.java

C:\Users\Chan\Desktop\Java Practice Programs>java TestEnums
SISSY

So should I conclude that enum references are not compile time constants?

Steve Luke wrote:
Chan Ag wrote:...
4. Dog variable a is not a constant as it is not final. So it cannot be a compile time constant.

Would that be correct?

That would all be correct, but if the variable a was declared as final Dog a = new Dog(); it would still not be a constant variable. Why is that?


It would not be a compile time constant as the objects are created and bound to references at runtime. But after an object is created and bound to the reference, we cannot reassign anything else to it. But we can still manipulate this variable's non constant instance variables. Is that why you say it's not a constant?

Greetings,
Chan.

 
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chan Ag wrote:So should I conclude that enum references are not compile time constants?


Logically we can consider them as such for a some purposes, but the JLS doesn't include them in its definition of a compile-time constant expression. (http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28)

 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First things first.. A big thanks to all you guys for responding to not only this thread of mine, but also to countless other threads and hence making learning a better experience for me and many. Not that you guys don't find it interesting.. just it also makes a big difference to us who are trying to learn programming. And it's incredible how wisely you guys provide the exact direction/education/guidance/pointers needed - not more, not less... It's a talent in itself. Sometimes it's also about having people around you to tell you, 'hey you're wrong', or 'you're right'... or 'why don't you try this'.. or 'if you had read the API, you would have the answer'. I wish I knew about coderance earlier ( I must have lived in isolation! ).

Coming back to compile time constants and enum constants, I'll remember these points.

Steve, was there more to why a Dog variable can never be a constant?

Chan.
 
Marshal
Posts: 56600
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote: . . . Logically we can consider them as such for a some purposes, . . .
The three days can be enum elements, but their constructor sets them up as different objects with different instance fields every time that class is loaded. If “constants” have the same internal state, then those enum elements are not compile‑time constants.
One cannot ∴ say that enum elements are implicitly constants.
 
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, they're not compile-time constants, certainly. The term "constant" is not really well-defined in Java, other than for a compile-time constant. And so it means different things to different people.

Chan, if you re-read the requirements for a compile-time constant, there's one very specific reason why a Dog variable can't be a constant.
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike Simmons wrote:Well, they're not compile-time constants, certainly. The term "constant" is not really well-defined in Java, other than for a compile-time constant. And so it means different things to different people.

Chan, if you re-read the requirements for a compile-time constant, there's one very specific reason why a Dog variable can't be a constant.

The term constant, as far as I can find, is found in two places: two describe the Constant Variable:
§4.12.4
A variable of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28), is called a constant variable.

And to describe Compile Time Constant Expressions:
§15.28 as quoted elsewhere.

The Dog is not a Constant Variable, because it is not a primitive or String type. Plain an simple. It is not a Compile Time Constant Expression because it is not a primitive or String literal, or anything that can be resolved to one as per the rules defined in §15.28.

So final Dog a = Dog.SASSY; is not even a Constant, let alone a compile time constant
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, I omitted constant variables, as they're kind of a subtype of constant expressions; my point was that they never define "constant" in general. They also talk about enum constants elsewhere. And then there's advice on naming conventions in JLS 6.1:

Constant Names

The names of constants in interface types should be, and final variables of class types may conventionally be, a sequence of one or more words, acronyms, or abbreviations, all uppercase, with components separated by underscore "_" characters. Constant names should be descriptive and not unnecessarily abbreviated. Conventionally they may be any appropriate part of speech.

However, in practice this convention for names of "constants" gets applied to many things that are not compile-time constant, or enum constants. Because, well, they never defined what they mean here.
 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the idea behind compile‑time constants was to restrict the range of different types, in order that the compiler can be sure they are constants. I know this is a constant, and so do you… but imagine how much work it would take to program the compiler to identify every immutable class and recognise its objects as compile‑time constants.
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Jeff Verdegan wrote: . . . Logically we can consider them as such for a some purposes, . . .
The three days can be enum elements, but their constructor sets them up as different objects with different instance fields every time that class is loaded. If “constants” have the same internal state, then those enum elements are not compile‑time constants.
One cannot ∴ say that enum elements are implicitly constants.



but imagine how much work it would take to program the compiler to identify every immutable class and recognise its objects as compile‑time constants.


Wow .. Those explain the whys.. Thanks.

Cheers.

P.S : BTW that enum code is gonna help me complete my assignment. As a part of my current assignment, I'm also working on a credit card application that computes if the due date is past for payment. This enum way to have a Due date enum value seems like a wonderful idea. Thanks.



 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well done
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:Logically we can consider them as such for a some purposes


Apparently that comment has led to some confusion. Rather than trying to clarify, I retract it. Just stick to what the JLS says.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:I think the idea behind compile‑time constants was to restrict the range of different types, in order that the compiler can be sure they are constants. I know this is a constant, and so do you… but imagine how much work it would take to program the compiler to identify every immutable class and recognise its objects as compile‑time constants.


Actually I don't think it would be that much work. And it would be necessary if Java were ever to implement the immutable keyword that I've been wishing for for so long now.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Chan Ag wrote:
P.S : BTW that enum code is gonna help me complete my assignment. As a part of my current assignment, I'm also working on a credit card application that computes if the due date is past for payment. This enum way to have a Due date enum value seems like a wonderful idea. Thanks.


I wouldn't advise using a YESTERDAY, TODAY, TOMORROW enum like the one above for that. You'd be locking in those days at the moment you launch your program. If it stays up and running overnight, those enum values will no longer match their names, and they won't be useful for the purpose of determining if something is past due.

You don't want to be using dates that are tied to when the program was launched, unless you're actually computing something related to when the program was launched.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote:You'd be locking in those days at the moment you launch your program...

I totally agree with what you're saying, but I could certainly see the value of a function that can return those enum constants (I think I might add PAST and FUTURE just for completeness; although you could also return null).

But then the question becomes "what is YESTERDAY"? My whole bleedin' life as far as I'm concerned...

Winston
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:
Jeff Verdegan wrote:You'd be locking in those days at the moment you launch your program...

I totally agree with what you're saying, but I could certainly see the value of a function that can return those enum constants (I think I might add PAST and FUTURE just for completeness; although you could also return null).


Right. It's not the constants themselves that are problematic. It's only if we define them relative to whatever "now" is when the class gets loaded and then use that "now" for determining which constant applies, even when that "now" is long gone.

 
Campbell Ritchie
Marshal
Posts: 56600
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jeff Verdegan wrote: . . .
I wouldn't advise using a YESTERDAY, TODAY, TOMORROW enum like the one above for that.
. . .
I didn't write it as a recommendation. I wrote it as an example where the enum constants were definitely not compile‑time constants.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:
Jeff Verdegan wrote: . . .
I wouldn't advise using a YESTERDAY, TODAY, TOMORROW enum like the one above for that.
. . .
I didn't write it as a recommendation. I wrote it as an example where the enum constants were definitely not compile‑time constants.


I didn't think you did.

But the OP picked up on it and said he was going to use it or something like it. I didn't know how literally he was going to take it so I just wanted to warn him about a possible pitfall.
 
Chan Ag
Rancher
Posts: 1090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Greetings,

Yeah, I figured out later that enum values wouldn't fit my requirement for the suggested reasons. Having said that, I still like that enum code cause it sets the state at the time you assign something to an enum reference. I hadn't seen such a code snippet earlier. I had often wondered if java provided some mechanism to do some minimal processing ( along the lines of evaluation of a constant like expression based on run time things ) at the time of assigning values to references and without creating instances, it would be great. When I say the above statement, I don't mean doing so by writing dirty code that defeats the very purpose of why any construct was made available in Java.

I'm still in the process of developing my understanding of how basic things work in java. So I will understand if what I said sounds stupid :-) It seems there are endless things to know and every time I read about one thing, I end up forgetting the subtle things about something I had read earlier :-) Sometimes I wonder what it takes to remember the exact method to be used.. what API to consult... cause there is SO MUCH to know

Later when I'm actually working on my credit card assignment, I'll work out my instance specific methods to compute the various dates.

Thanks for all your suggestions and pointers. It has been a great help..

Chan



 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!