Where to store constants in Java/Android?


Hello.

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

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

Protected interface AlarmsColumns extends AlarmSettingColumns, BaseColumns

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

ClockContract.InstancesColumns._ID

Everything was fine if used from a class in one package, and if the class is in another package-when trying the IDE wrote a completely logical error about accessing protected. You can also borrow only if you are in the same package. Although, after reading the official docks and the Internet, storing constants in the interface is considered kind of antipattern.

Please explain why this was done? How they work protected/private interface and where is it better to store constants?
Thank you in advance.

Author: rjhdby, 2014-09-10

1 answers

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

In public static final class fields or in public Enum's (such as here and here).

What private / protected interfaces are used for. They, in turn, contain constants ... for which it was made so

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

How protected/private intfaces work

Take this 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 descendant classes (even from other packages). Inheritors don't have to write A. to access internal classes/interfaces and static ones. fields.
  • A_PRIVATE_INTERFACE_CONST available only inside class A (including in internal class/interface/enum)
  • A_PROTECTED_INNER_CLASS_CONST is available to classes in the same package. This protected constant is not directly accessible to the inheritors of other packages. However, the protected class itself is available to all inheritors, and you can inherit from it to get the value of this constant (see class D). You can set a different name (static members are still not inherited), or you can overwrite it with the same name. the same name.
  • A_CONST is available to classes in the same package and to descendant 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 related to the{[37] class]}
    • In the nested class/interface/enum - if several constants can be grouped by meaning, 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 set access:

    • public - if the constant is widely used by other classes
    • protected - if the constant is used inside a package or it makes sense to allow it to be used in descendant classes, restricting access to all to the rest
    • private - if the constant is used only inside the class
 5
Author: bromzh, 2016-08-24 09:01:18