Global constants in Groovy

前端 未结 4 1113
名媛妹妹
名媛妹妹 2021-01-31 14:17

It is often desired to declare constants at the top of a script that can be referenced anywhere else in the script. In Groovy, it seems that if you declare a constant using fin

相关标签:
4条回答
  • 2021-01-31 14:26

    In Groovy 1.8+, you can achieve this using the @Field annotation:

    import groovy.transform.Field
    
    @Field final String MY_CONSTANT = 'constant'
    
    def printConstant() { println MY_CONSTANT }
    
    printConstant()
    
    0 讨论(0)
  • 2021-01-31 14:30

    I personally wouldn't do it but technically you could do

    Object.metaclass.MYCONSTANT = 'foobar'

    Then every object has it

    0 讨论(0)
  • 2021-01-31 14:36

    The another efficient way to add the global application level constants are declare one interface in suitable package as

    interface applicationConstants {
    //All constants goes here.
        static final float PI = 3.14 
        String ADMIN_USER = "ADMIN"
        Map languages = [
            "en":   "English",
            "hi":   "Hindi",
            "mr":   "Marathi"
    
        ]
    // Like above you can declare all application level code constants here.
    
    }
    

    Use of constants in any class as below,

     import packageNameContainingInterface.applicationConstants // import statement.
     def adminUser = applicationConstants.ADMIN_USER
     println adminUser
    
    0 讨论(0)
  • 2021-01-31 14:44

    Groovy doesn't really have a global scope. When you have a groovy script that doesn't declare a class, it implicitly gets stuck in a class with the name of the script. So final variables at the top-level scope are really just fields of the implicit class. For example:

    // foo.groovy
    final MYCONSTANT = "foobar"
    println MYCONSTANT
    
    class Helper {
        def hello() { println MYCONSTANT }  // won't work
    }
    new Helper().hello()
    

    Is more or less equivalent to:

    class foo {
        def run() {
            final MYCONSTANT = "foobar"
            println MYCONSTANT
            new Helper().hello()
        }
        static main(args) {
            new foo().run()
        }
    }
    
    class Helper {
        def hello() { println MYCONSTANT }  // won't work
    }
    

    It's easy to see why it doesn't work expanded out. An easy work around is to declare your "globals" in a dummy class called e.g. Constants, and then just do a static import on it. It even works all in a single script. Example:

    import static Constants.*
    
    class Constants {
        static final MYCONSTANT = "foobar"
    }
    
    println MYCONSTANT
    
    class Helper {
        def hello() { println MYCONSTANT } // works!
    }
    new Helper().hello()
    

    EDIT:

    Also, scripts are bit of a special case. If you declare a variable without def or any modifiers such as final, (i.e. just use it) it goes into a script-wide binding. So in this case:

    CONSTANT = "foobar"
    println "foobar"
    

    CONSTANT is in the script-wide binding, but in:

    final CONSTANT = "foobar"
    println "foobar"
    

    CONSTANT is a local variable in the script's run() method. More information on this can be found at https://web-beta.archive.org/web/20150108090004/http://groovy.codehaus.org/Scoping+and+the+Semantics+of+%22def%22

    0 讨论(0)
提交回复
热议问题