Question

For example:

public void doSomething() {

    final double MIN_INTEREST = 0.0;

    // ...  
}

Personally, I would rather see these substitution constants declared statically at the class level. I suppose I'm looking for an "industry viewpoint" on the matter.

Was it helpful?

Solution

My starting position is that every variable or constant should be declared/initialized as close to it's first use as possible/practical (i.e. don't break a logical block of code in half, just to declare a few lines closer), and scoped as tightly as possible. -- Unless you can give me a damn good reason why it should be different.

For example, a method scoped final won't be visible in the public API. Sometimes this bit of information could be quit useful to the users of your class, and should be moved up.

In the example you gave in the question, I would say that MIN_INTEREST is probably one of those pieces of information that a user would like to get their hands on, and it should be scoped to the class, not the method. (Although, there is no context to the example code, and my assumption could be completely wrong.)

OTHER TIPS

I would think that you should only put them at the class level if they are used by multiple methods. If it is only used in that method then that looks fine to me.

Technically, there is no such thing as a "method scoped constant" in Java. What you are referring to is simply a final local variable; it is created an destroyed with each method invocation.

http://www.java-tips.org/java-se-tips/java.lang/how-do-i-declare-a-constant-in-java.html

Information hiding and modularity are key principles, and narrow scoping is better information hiding. If the constant is only needed by the method, the hiding is good. If and when the constant is useful elsewhere, bring it out to a broader scope, but only as broadly as needed.

You are probably concerned because this is a constant, and therefore, it may seem to belong to some global properties table. Maybe it does. Maybe it doesn't. Your concern is valid, but there is no one best place for all constants.

I've used this method scoped constants myself but every so often a colleague will down mod it during code reviews. Again, these colleagues are not into reading/writing open source but they are used to enterprise software.

I tell them that it does NOT make sense to use a class level constant if it is used within a single method but I've found more than 1 colleague insisting that it be moved UP. I usually comply since I'm not so rigid unless it affects readability and/or performance.

I have a different take on this: IMHO its better to place them at file/class scope especially if you are working in teams for this reason: say you start with a small piece of code...

public void doSomething() {

  final double MIN_INTEREST = 0.0;

  // ...  
}

and other members of you team expand the class with whole bunch of methods and now the class is a wonderful 500 lines/50 methods giant class. Imagine the experience of an engineer who is trying to adding a new method with a constant, they will have to 1 scan the whole class looking for constants that match their need, 2 move the constant to class scope hoping that there are no conflicts with existing code and 3 also add their method.

If you instead add all constants at file/class scope to begin with, engineers have a 1 single place to look for existing constants and, 2 derive some constants from others where it makes sense. (for example if you have a constant for pi you may also want to define a new constant with a value of pi/2).

The reason why you can define a final variable at a class level or method (local) level it's because you can override the global static constant inside the (local) method.

Example:

public class Test {

    final double MIN_INTEREST = 0.0;

    /**
     * @param args
     */
    public static void main(String[] args) {


        Test test = new Test();

        test.doSomethingLocal();
        test.doSomethingGlobal();

    }

    public void doSomethingGlobal() {

        System.out.println("Global-> " + MIN_INTEREST);

    }

    public void doSomethingLocal() {

        final double MIN_INTEREST = 0.1;

        System.out.println("Local-> " + MIN_INTEREST);

    }
}

The output will be:

Local-> 0.1
Global-> 0.0

So your question doesn't make any sense.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top