4

In java, if a variable is immutable and final then should it be a static class variable?

I ask because it seems wasteful to create a new object every time an instance of the class uses it (since it is always the same anyway).

Example:

Variables created in the method each time it is called:

public class SomeClass {

    public void someMethod() {

        final String someRegex = "\\d+";
        final Pattern somePattern = Pattern.compile(someRegex);

        ...

    }

}

Variables created once:

public class SomeClass {

    private final static String someRegex = "\\d+";
    private final static Pattern somePattern = Pattern.compile(someRegex);

    public void someMethod() {

        ...

    }

}

Is it always preferable to use the latter code?

This answer seems to indicate that it is preferable to use the latter code: How can I initialize a String array with length 0 in Java?

theyuv
  • 1,556
  • 4
  • 26
  • 55

2 Answers2

6

No definitely not.

class MyIntegerContainer{
    private final int x;
    public MyIntegerContainer(int x){
        this.x = x;
    }
}

If you made immutable, final x static, then all instances of MyIntegerContainer would share the same value of x which would not make for a very good data container.

Blake
  • 986
  • 9
  • 24
  • 1
    Right, `static` is for class variables, values that are the same across all instances of a class. If that's what you want, then use `static`. `final` instance variables are useful and quite common. – markspace Mar 14 '18 at 15:45
  • Going along with @markspace comment, if, for example, you wanted a constant, it would be good to make it `public static final`. (public only if other classes will need the constant) – Blake Mar 14 '18 at 15:46
  • I should reword the question, this is not a case I was referring to. – theyuv Mar 14 '18 at 16:07
  • Concerning your example: in the first case, the two variables`someRegex` and `somePattern` are _local variables_, meaning they will fall out of scope once the method block has completed and will be cleared by the GC very soon. In the second case, whenever an instance of the class exists, memory will be allocated to your the class variables and shared among all instances. If there are many instances and the method `someMethod` is running simultanously in different threads, then the second case would be beneficial, otherwise it makes little difference. – Blake Mar 14 '18 at 21:07
1

Ultimately it depends on what you're doing with those variables.

If the variable only ever has a lifecycle inside of that specific method - that is, nothing else will ever need to see it or use those values - then declaring them inside of the method is appropriate and correct. Making it more visible than it needs to only adds to confusion for future maintainers (including yourself).

If the variable has a lifecycle outside of the class, it might make sense to declare it static. This is particularly true in the case of constants or variables that don't store any state themselves.

If it isn't a constant or it doesn't have any purpose outside of the class, then keep it non-static and private.

Makoto
  • 104,088
  • 27
  • 192
  • 230
  • The answer here: https://stackoverflow.com/questions/1665834/how-can-i-initialize-a-string-array-with-length-0-in-java/1665899#answer-1665899 suggests that if you have an immutable Object that you plan to reuse, you might as well make it static. Did I misunderstand it? – theyuv Mar 14 '18 at 15:52
  • 1
    @theyuv: It only makes sense because that variable has a lifecycle outside of that class, so it makes sense to allow it to be a constant *from* that class. The hard-and-fast rule is simple: if you're going to use it in more than one place and you don't want or can't instantiate an instance of your object to get it, then make it static. Otherwise, keep it non-static. – Makoto Mar 14 '18 at 15:53
  • thanks. If an immutable, final variable was reused in the same method of the same class, it shouldn't be made a static class variable? I shouldn't consider the fact that it is recreated every time the method is called?... In the linked answer, the variable is `private`. How is it used "outside of the class". Thanks again. – theyuv Mar 14 '18 at 16:03
  • I'd argue that declaring it `private` is a misnomer. It'll never leave that class and no child will ever see it. It *probably* shouldn't be static in that context. – Makoto Mar 14 '18 at 16:07
  • @theyuv no you shouldn't worry that the variable is recreated everytime the method is called because, as i commented in my answer, those variables are `thread local` and will be obliterated by the garbage collector after the method is finished executing! – Blake Mar 14 '18 at 18:43
  • As for the link you commented above, yes I believe you're misinterpreting it. The answer does not suggest that any immutable _objects_ that you plan to reuse should be static. Instead it suggests that any immutable _fields_ that you plan to reuse should be static. Big difference. – Blake Mar 14 '18 at 18:51
  • Can you explain the difference please? Maybe with an example... An `Object` can be a `field`. – theyuv Mar 15 '18 at 07:33