Win a copy of Learn Java with Math: Using Fun Projects and Games this week in the Beginning Java forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Junilu Lacar
  • Martin Vashko
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Scott Selikoff
  • salvin francis
  • Piet Souris

What is a compile time constant?

 
author
Posts: 23844
141
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Likes 20
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It is amazing how many times a question comes up in this forum, where the answer is something like... "Because X is a compile time constant, the compiler will Y"... But what exactly is a compile time constant? And how can we determine whether something is treated as such?

Obviously, a compile time constant is a constant value that is known at compile time... ... Literals are, by definition, compile time constants -- as they are constants, known at compile time.

But the definition of a compile time constant is a bit more complex. To start, let's examine section 15.28 of the Java language specification.

15.28 Constant Expression

A compile-time constant expression is an expression denoting a value of primitive type or a String that is composed using only the following:

  • Literals of primitive type and literals of type String
  • Casts to primitive types and casts to type String
  • The unary operators +, -, ~, and ! (but not ++ or --)
  • The multiplicative operators *, /, and %
  • The additive operators + and -
  • The shift operators <<, >>, and >>>
  • The relational operators <, <=, >, and >= (but not instanceof)
  • The equality operators == and !=
  • The bitwise and logical operators &, ^, and |
  • The conditional-and operator && and the conditional-or operator ||
  • The ternary conditional operator ? :
  • Simple names that refer to final variables whose initializers are constant expressions
  • Qualified names of the form TypeName . Identifier that refer to final variables whose initializers are constant expressions



  • This is the full definition of a compile time constant. And as you can see, it contains more than just literals. In fact, literals are merely the first bullet point on the list. Also, note that a compile time constant can apply to any literal that is of primative or String type.

    The next few bullet points are the operations that can be applied to a constant at compile time. This list is actually pretty long, as it is possible to apply most of the operations at compile time. It may actually be easier to remember what can't be apply at compile time -- pre and post increment and decrement, instanceof operator, or any method calls, are not on the list.

    The last few bullets are the most interesting. It is possible to use a variable in the expression -- provided that the variable is a compile time constant variable. So... what is a constant variable? Going back to the JLS (section 4.12.4 to be exact)...

    4.12.4 final Variables

    A variable can be declared final. A final variable may only be assigned to once. It is a compile time error if a final variable is assigned to unless it is definitely unassigned (§16) immediately prior to the assignment.

    [BLAH BLAH BLAH]

    We call a variable, of primitive type or type String, that is final and initialized with a compile-time constant expression (§15.28) a constant variable. Whether a variable is a constant variable or not may have implications with respect to class initialization (§12.4.1), binary compatibility (§13.1, §13.4.9) and definite assignment (§16).



    The last part of the definition is the relevant part (I still find it amazing that this is that well hidden in the specification). To be a variable that is a compile time constant, the variable needs to be...

  • declared as final
  • have a primative or String type
  • initialized (on the same line as the declaration)
  • assigned to a compile time constant expression





  • Obviously, I am somewhat bored this morning... ...But hopefully... now when someone say, "what's a compile time constant", or "because X is a compile time constant", you know the long specification definition of what it is.

    Hope this helps,
    Henry
     
    author and cow tipper
    Posts: 5000
    1
    Hibernate Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This is an awesome, and definitely helpful resource.

    Just in case anyone was looking for it, here's a link to the Java Language Specification from Sun which was referenced by Henry:

    Java Language Specification from Sun

    -Cameron McKenzie
     
    Greenhorn
    Posts: 6
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This is a good detailed information..which i was looking for. Last four points related to "To be a variable that is a compile time constant, the variable needs to be... " are very helpful.
    Thanks
     
    Henry Wong
    author
    Posts: 23844
    141
    jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    ash aj wrote:This is a good detailed information..which i was looking for. Last four points related to "To be a variable that is a compile time constant, the variable needs to be... " are very helpful.
    Thanks



    Thanks for the feedback. I'm grateful. In thinking about it a bit more, maybe it could be tighten up. Instead of this...

  • initialized (on the same line as the declaration)


  • Maybe this would read better...

  • initialized (at the same time as the declaration)


  • Henry

     
    Ranch Hand
    Posts: 40
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I am sorry, new to Java Ranch, do we store these kind of articles elsewhere or this thread will be the only source, because this is really helpful.
     
    Henry Wong
    author
    Posts: 23844
    141
    jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Raghu Devatha wrote:I am sorry, new to Java Ranch, do we store these kind of articles elsewhere or this thread will be the only source, cuz this is really helpful.



    This topic was added to the FAQ...

    http://faq.javaranch.com/java/JavaBeginnersFaq


    Henry
     
    Marshal
    Posts: 66467
    250
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    You will have to learn your way around the API documentation, Java Language Specification, etc. You may prefer to keep your own notes. And this thread will most probably remain available as long as JavaRanch lasts.

    Please don't say "cuz": read this FAQ
     
    Campbell Ritchie
    Marshal
    Posts: 66467
    250
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Bora Sabrioglu,
    Your post was moved to a new topic.
    (This informational message will self destruct in two days)


    [NOTE: Normally, this post will "self destruct". However, since the post that was moved has an interesting discussion, I think it would be good to keep this link.]
     
    Greenhorn
    Posts: 11
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Henry Wong wrote:
    The last part of the definition is the relevant part (I still find it amazing that this is that well hidden in the specification). To be a variable that is a compile time constant, the variable needs to be...

  • declared as final
  • have a primative or String type
  • initialized (on the same line as the declaration)
  • assigned to a compile time constant expression

  • Did you mean one of the options or all of them?
    it can be final but not initialized (on the same line as the declaration)?
     
    Ranch Hand
    Posts: 491
    23
    Eclipse IDE Firefox Browser Spring VI Editor AngularJS Java
    • Likes 3
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Maor wrote:Did you mean one of the options or all of them?

    All of them.as for example:
    final String = getSomeString();
    is not a compile time constant because getSomeString() is not a constant expression(it would be known during run-time when it is invoked).

    Praveen.
     
    Greenhorn
    Posts: 1
    Python Debian Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I came across with the following situation regarding this thread, but was unable to answer my question.

    This code compile:



    This code does not compile:



    Ok.. i get it "initialized (on the same line as the declaration)" to be a compile time constant.
    But how can i assign final to a variable if it will not be treated like a constant?
    Was I misunderstanding the concept of final?

    In my head, both the cases are valid, since i don't try to assign values to the final variable more than once, wich is impossible.

    Why Java work like this? Which seems to be completely meaningless.

    As you can see, this is a broad question.. So I go straight to what I consider to be the main one: How can java understand and interpret the difference between these two code above?

    I'm only asking this, because i can't find anything to help(not even in Java Spec). I'm not looking for the rule which says "initialize in th same line as the declaration", i'm looking fo something like "when you try to assign after the declaration, the compiler will undestand that and that and blah blah blah".

    Can some help me?





     
    Campbell Ritchie
    Marshal
    Posts: 66467
    250
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Welcome to the Ranch

    Remember that your switch is translated by the javac tool into a lookup table in the bytecode. You can inspect it with the javap tool:-You can see that passing 2 will take you to No 28 and 5 takes you to 36 and because you didn't write break; you would get fall‑through.
    Now, how would you initialised varB otherwise? What if you had code like this:-You can tell by looking what the value of varB is. You would have to use sixteen tokens' look‑ahead to find 7, and then go back those sixteen tokens and attribute that value to varB. That is something almost impossible for a compiler to do, and even if you did manage it, the compiler would run with all the speed of a dying snail. A large program which takes a few hours to compile would take all year to compile And what if the value of varB couldn't be determined at compile time:-You are now in a situation whee it is impossible to predict the value of varB but the compiler needs to know that value to write the lookup table. So it cannot compile the code. It is too difficult to implement compilation if the cases aren't compile‑time constants.
     
    Rancher
    Posts: 3404
    33
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I agree with Campbell's answer, which I think addresses the main issue for you.  But also:

    Bruno Pinheiro wrote:I'm only asking this, because i can't find anything to help(not even in Java Spec). I'm not looking for the rule which says "initialize in th same line as the declaration", i'm looking fo something like "when you try to assign after the declaration, the compiler will undestand that and that and blah blah blah".



    I think you're looking for the rules for definite assigment.  Those are useful to know about.  But be aware, that's a little different than the rules for a compile-time constant.  Definite assignment basically means a local variable or final field must be set to something, before it is used (read).  However, that something isn't necessarily known at compile time.

    It's also true that you can find examples where, although the rules for a compile-time constant haven't been met, we can see, clearly, that the value of the variable could be known, exactly, at compile time, so why didn't they write the rules differently?  Well, we may never really know, but I suspect they were simplifying their jobs (and ours) by not putting in more complicated rules to handle cases that weren't that useful.  I would argue that, if there's only one constant value that a variable can be, then there's no good reason not to simply initialize it to that value at the time it's declared.  And then it would be a compile-time constant.  If there's more than one possible value, then you can't do that, and it's not a compile-time constant.
     
    Saloon Keeper
    Posts: 21300
    140
    Android Eclipse IDE Tomcat Server Redhat Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator

    Campbell Ritchie wrote:Welcome to the Ranch

    Remember that your switch is translated by the javac tool into a lookup table in the bytecode.



    Except when it isn't. Sparse-value switches, for example.

    While the old expression "Constants - aren't and variables - won't" is a classic, what you have here is two different classes of "constants".

    The form "final int varB = 7;" is defining a Manifest Constant. Essentially, it's treated as though you'd always coded the actual value 7 wherever you code varB.

    The failing form, however is being treated as an immutable variable. It's functionally the same as a manifest constant except that being defined and initialized in 2 different places means that the compiler must treat it differently (for example, checking for use before initialization and checking for multiple initializations).

    My felling is that the compiler probably could treat the two situations identically, but the implementors weren't willing to go to the extra work to ensure it would be so. What if, for example, initialization was done in a base class?

    And this is one of the reasons why Java uses the keyword "final" instead of being like C++ and calling it "const".
     
    Marshal
    Posts: 7295
    497
    Mac OS X VI Editor BSD Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Henry Wong,

    CowGratulations, your topic has been published in our CodeRanch Journal August Edition.

    A copy of journal you could find here -> https://coderanch.com/wiki/715405/CodeRanch-Journal-August
    Other than that, you, as everybody else supposed to get one emailed to you
     
    Ranch Hand
    Posts: 79
    1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator


    [code=java] public static void main(String[] args) {
    final int varA = 2;
    final int varB;
    varB = 7;  //Evething ok here
    switch (0) {
    case varA:
    System.out.println("1");
    case varB: //Compile error: Case expressions must be constant expression
    System.out.println("");
    }
    }[/code
    Hello..
    See compile time constant means it is determined at compile time
    But you have not given any value to varB at declaration instead you have assigned a value
    varB=7; this code determined at runtime, which means in future the value of varB may change, like
    varB = 9; so value may change that's why it is not final variable, if you want final variable it must be initialized at the time declaration so that it's value should not change
    Hope this helps.....
     
    Rancher
    Posts: 260
    12
    IntelliJ IDE Spring Java
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    @Sohail, your code tags are missing a ] at the end, which causes the code to look as normal text.  
     
    Campbell Ritchie
    Marshal
    Posts: 66467
    250
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    This is what the code looks like with the ] corrected
     
    Greenhorn
    Posts: 1
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Thank you for this post! Posted 10 years ago and still helpful.
     
    Weeds: because mother nature refuses to be your personal bitch. But this tiny ad is willing:
    Java file APIs (DOC, XLS, PDF, and many more)
    https://products.aspose.com/total/java
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!