Skip to main content

#define in Java


I'm beginning to program in Java and I'm wondering if the equivalent to the C++ #define exists.



A quick search of google says that it doesn't, but could anyone tell me if something similar exists in Java? I'm trying to make my code more readable.



Instead of myArray[0] I want to be able to write myArray[PROTEINS] for example.


Source: Tips4all

Comments

  1. No, because there's no precompiler.

    However, Hotspot is quite amazingly good at optimising where possible, so in your case you could achieve the same thing as follows:

    class MyClass
    {
    private static final int PROTEINS = 0;

    ...

    MyArray[] foo = new MyArray[PROTEINS];

    }


    The compiler will notice that PROTEINS can never, ever change and so will inline it which is more or less what you want.

    Note that the access modifier on the constant is unimportant here, so it could be public or protected instead of private, if you wanted to reuse the same constant across multiple classes.

    ReplyDelete
  2. Comment space too small, so here is some more information for you on the use of static final. As I said in my comment to the Andrzej's answer, only primitive and String are compiled directly into the code as literals. To demonstrate this, try the following:

    You can see this in action by creating three classes (in separate files):

    public class DisplayValue {
    private String value;

    public DisplayValue(String value) {
    this.value = value;
    }

    public String toString() {
    return value;
    }
    }

    public class Constants {
    public static final int INT_VALUE = 0;
    public static final DisplayValue VALUE = new DisplayValue("A");
    }

    public class Test {
    public static void main(String[] args) {
    System.out.println("Int = " + Constants.INT_VALUE);
    System.out.println("Value = " + Constants.VALUE);
    }
    }


    Compile these and run Test, which prints:


    Int = 0
    Value = A


    Now, change Constants to have a different value for each and just compile class Constants. When you execute Test again (without recompiling the class file) it still prints the old value for INT_VALUE but not VALUE. For example:

    public class Constants {
    public static final int INT_VALUE = 2;
    public static final DisplayValue VALUE = new DisplayValue("X");
    }


    Run Test without recompiling Test.java:


    Int = 0
    Value = X


    Note that any other type used with static final is kept as a reference.

    Similar to C/C++ #if/#endif, a constant literal or one defined through static final with primitives, used in a regular Java if condition and evaluates to false will cause the compiler to strip the byte code for the statements within the if block (they will not be generated).

    private static final boolean DEBUG = false;

    if (DEBUG) {
    ...code here...
    }


    The code at "...code here..." would not be compiled into the byte code. But if you changed DEBUG to true then it would be.

    ReplyDelete
  3. static final int PROTEINS = 1
    ...
    myArray[PROTEINS]


    You'd normalput "constants" in the class itself. And do note that a compiler is allowed to optimize references to it away, so don't change it unless you recompile all the using classes.

    class Foo {
    public static final int SIZE = 5;

    public static int[] arr = new int[SIZE];
    }
    class Bar {
    int last = arr[Foo.SIZE - 1];
    }


    edit cycle... SIZE=4. Also compile Bar because you compiler may have just written "4" in the last compilation cycle!

    ReplyDelete
  4. Java doesn't have a general purpose define preprocessor directive.

    In the case of constants, it is recommended to declare them as static finals, like in

    private static final int PROTEINS = 100;


    Such declarations would be inlined by the compilers (if the value is a compile-time constant).

    Please note also that public static final constant fields are part of the public interface and their values shouldn't change (as the compiler inlines them). If you do change the value, you would need to recompile all the sources that referenced that constant field.

    ReplyDelete

Post a Comment

Popular posts from this blog

[韓日関係] 首相含む大幅な内閣改造の可能性…早ければ来月10日ごろ=韓国

div not scrolling properly with slimScroll plugin

I am using the slimScroll plugin for jQuery by Piotr Rochala Which is a great plugin for nice scrollbars on most browsers but I am stuck because I am using it for a chat box and whenever the user appends new text to the boxit does scroll using the .scrollTop() method however the plugin's scrollbar doesnt scroll with it and when the user wants to look though the chat history it will start scrolling from near the top. I have made a quick demo of my situation http://jsfiddle.net/DY9CT/2/ Does anyone know how to solve this problem?

Why does this javascript based printing cause Safari to refresh the page?

The page I am working on has a javascript function executed to print parts of the page. For some reason, printing in Safari, causes the window to somehow update. I say somehow, because it does not really refresh as in reload the page, but rather it starts the "rendering" of the page from start, i.e. scroll to top, flash animations start from 0, and so forth. The effect is reproduced by this fiddle: http://jsfiddle.net/fYmnB/ Clicking the print button and finishing or cancelling a print in Safari causes the screen to "go white" for a sec, which in my real website manifests itself as something "like" a reload. While running print button with, let's say, Firefox, just opens and closes the print dialogue without affecting the fiddle page in any way. Is there something with my way of calling the browsers print method that causes this, or how can it be explained - and preferably, avoided? P.S.: On my real site the same occurs with Chrome. In the ex