3

Why would you declare a static final variable as private for an immutable type?

Could it possibly do any harm to declare them public on any case?

Andres
  • 10,561
  • 4
  • 45
  • 63
  • 5
    Just because the field is final, doesn't mean the object it references is immutable, so you may still need to encapsulate it. – Andreas Aug 08 '16 at 14:45
  • 1
    logger is a good example, see http://stackoverflow.com/questions/26241787/declaring-variable-final-and-static?rq=1 –  Aug 08 '16 at 14:45
  • 2
    Or just anything that does not _need_ to be exposed, to keep the API small. – tobias_k Aug 08 '16 at 14:46
  • 1
    Cluttering the public API of the class with constants that you don't want anyone to actually use feels kind of bad too. – Jite Aug 08 '16 at 14:46
  • The short answer to the second question is: yes. Sometimes it is important that no external code has any access to an object, because that's the only way to guarantee the correctness of your code. – biziclop Aug 08 '16 at 14:46
  • @Andreas And if you use the object for locking, even if it is "immutable", you don't want to expose it. – biziclop Aug 08 '16 at 14:49

4 Answers4

3

So that nobody can access it from outside and rely on that value, giving you the freedom to change it without risk of side-effect (at least outside of the class where it's declared).

Spotted
  • 4,021
  • 17
  • 33
3

There are serveral reasons...

Privacy

Keep implementation details hidden from the clients, for example constants for internal use only and with no use for clients

Security

Protect your code from maliscious client codes for example:

static class A
{
    public final static List<String> list = buildList();

    public static List<String> buildList()
    {
        ArrayList<String> list = new ArrayList<>();
        list.addAll(Arrays.asList("A", "B", "C"));
        return list;
    }
}

static class B
{
    public static void main(String[] args)
    {
        A.list.clear();
        System.out.println(A.list);
    }
}

You dont want any one to manipulate you internal data.

A4L
  • 17,353
  • 6
  • 49
  • 70
  • I think your example is inconsistent with your answer. `list` is not really protected, and can be modify. you can prevent it if build list will return `Collections.unmodifiableList(Arrays.asList("A", "B", "C"));` – user902383 Aug 10 '16 at 09:24
  • @user902383 that's what the example was for, i.e. to show that it is not protected since the question was about the point in having `private static final`, if the list was public or protected then it slould definitly be protected with an unmodifiable collection, just as you pointed in your comment or a copy. – A4L Aug 10 '16 at 09:28
  • does not matter what keywords you will use in declaration of your list, if provided implementation will be `ArrayList` it's content might be changed. – user902383 Aug 10 '16 at 09:40
  • @user902383 if the keywork is `private` then the change is only possible within the same class which should be allowed. Also then it does not matter how you initialize the list itself or wichi implementation you use since you could just assign a new list. – A4L Aug 10 '16 at 10:02
  • You are correct, you can't assign new list, but this was not my point. my point was, you can still replace content and because that does not guarantee you full security. – user902383 Aug 10 '16 at 10:16
0

It's just best OOP practice to keep variables within the proper scope. An example would be a global static final integer for performing a number of calculations within the class. Having it exposed (public) not only could cause problems, but confusion as well.

Say you had a class where you needed to know the value of pi:

public class MyClass {
    private static final double PI = 3.14159;

    //functions performing calculations with value of PI
}

The value of pi is only needed within MyClass, so leaving it to be exposed makes no sense - all calculations with the variable are done within MyClass. If you need it again to perform a calculation, it should be done within the class holding the value to keep your code organized.

Drew Kennedy
  • 4,118
  • 4
  • 24
  • 34
0
public class GUICommon {
    private static final ExecutorService executorServices = Executors.newWorkStealingPool();

    public static void useExecutors(Runnable run) 
    {
    executorServices.execute(run);
    }
}

I used it on this way.

Eric Chan
  • 49
  • 3
  • Welcome to [so]! Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others. – lucascaro Nov 09 '18 at 06:31