Hello.

I want to write the correct code, I wondered. After all, where is it better to store constants in Java? Now I pick the codes of standard Android applications. I met for myself a few controversial moments. I want to ask a few questions:

  1. Where is it better and better to store constants that are often used from other classes?
  2. What are private / protected interface ? They, in turn, contain constants. For example:

protected interface AlarmsColumns extends AlarmSettingColumns, BaseColumns

And the class in which such interfaces are declared is called Contract(ClockContract) . The constants themselves in the interface are declared as public static final . Initially, in the program code, constants were used like this:

ClockContract.InstancesColumns._ID

Everything was good, if used from a class in one package, and if the class is in another package, when trying to access, the IDE wrote a logical error about access to protected . You can also entrench only if you are in the same package. Although, after reading the official docks and the Internet, storing constants in the interface is considered to be antipattern.

Explain, please, why was this done? How do protected / private interface and where is it better to store constants?
Thanks in advance.

    1 answer 1

    Where is it better and better to store constants that are often used from other classes?

    In public static final fields of a class or in public Enum 'ah (like, for example, here and here ).

    What are private / protected interfaces used for? They, in turn, contain constants ... why it was so done

    This is most likely done to group constants and restrict access to them. Not all constants should be accessible from everywhere, some are needed only in the class, some only in the package and heirs.

    how do protected / private intrfaces work

    Take the following class hierarchy:

      |\ - Main.java | | - foo | |\ | | | - A.java | | | - B.Jjava | | | - C.java | | | | - bar | |\ | | | - D.java 

    And the code:

     // foo/A.java package foo; public class A { public static interface PublicInnerInterface { public static final int A_PUBLIC_INNER_INTERFACE_CONST = 0; } protected static interface ProtectedInnerInterface { public static final int A_PROTECTED_INNER_INTERFACE_CONST = 1; } private static interface PrivateInnerInterface { public static final int A_PRIVATE_INTERFACE_CONST = 2; } protected static class InnerClass { protected static final int A_PROTECTED_INNER_CLASS_CONST = 3; } protected static final int A_CONST = PrivateInnerInterface.A_PRIVATE_INTERFACE_CONST; } // foo/B.java package foo; public class B { public void test() { System.out.println("B -> A_PROTECTED_INNER_INTERFACE_CONST: " + A.ProtectedInnerInterface.A_PROTECTED_INNER_INTERFACE_CONST); System.out.println("B -> A_PROTECTED_INNER_CLASS_CONST: " + A.InnerClass.A_PROTECTED_INNER_CLASS_CONST); System.out.println("B -> A_CONST: " + A.A_CONST); } } // foo/C.java package foo; public class C extends A { public void test() { System.out.println("C -> A_PROTECTED_INNER_INTERFACE_CONST: " + ProtectedInnerInterface.A_PROTECTED_INNER_INTERFACE_CONST); System.out.println("C -> A_PROTECTED_INNER_CLASS_CONST: " + InnerClass.A_PROTECTED_INNER_CLASS_CONST); System.out.println("C -> A_CONST: " + A_CONST); } } // bar/D.java package bar; import foo.A; public class D extends A { protected static class InnerClass extends A.InnerClass { public static final int A_PROTECTED_INNER_CLASS_CONST = A.InnerClass.A_PROTECTED_INNER_CLASS_CONST + 10; } public void test() { System.out.println("D -> A_PROTECTED_INNER_INTERFACE_CONST: " + ProtectedInnerInterface.A_PROTECTED_INNER_INTERFACE_CONST); System.out.println("D -> A_PROTECTED_INNER_CLASS_CONST: " + InnerClass.A_PROTECTED_INNER_CLASS_CONST); System.out.println("D -> A_CONST: " + A_CONST); } } // Main.java import bar.D; import foo.A; import foo.B; import foo.C; public class Main { public static void main(String[] args) { System.out.println("Main -> A_PUBLIC_INNER_INTERFACE_CONST: " + A.PublicInnerInterface.A_PUBLIC_INNER_INTERFACE_CONST); B b = new B(); b.test(); C c = new C(); c.test(); D d = new D(); d.test(); } } 
    • A_PUBLIC_INNER_INTERFACE_CONST available everywhere
    • A_PROTECTED_INNER_INTERFACE_CONST is available to classes in the same package and to successor classes (even from other packages). Heirs do not need to write A. to access internal classes / interfaces and static fields.
    • A_PRIVATE_INTERFACE_CONST is available only inside class A (including the internal class / interface / enum)
    • A_PROTECTED_INNER_CLASS_CONST is available to classes lying in the same package. This protected constant is not directly accessible to heirs in other packages. However, the protected class itself is available to all heirs and can be inherited from it to get the value of this constant (see class D ). You can set another name (static members are not inherited anyway), but you can also overwrite it with the same name.
    • A_CONST is available to classes lying in the same package and to successor classes (even from other packages).

    In general, there is no general clear agreement, it all depends on the meaning of the constant.

    • Where to store:

      • In the class itself - if the constant is directly connected to the class
      • In a nested class / interface / enum - if several constants can be grouped in a meaningful way, but they are still closely related to the class itself
      • In a separate class / interface / enum - if several constants can be grouped, but they make sense outside of any class
    • How to put access:

      • public - if the constant is widely used by other classes
      • protected - if a constant is used inside a package or it makes sense to allow it to be used in successor classes, restricting access to all others
      • private - if the constant is used only inside the class