Java: Access Specifiers

By Xah Lee. Date: . Last updated: .

In Java code, class and variable and method and constructor declarations can have “access specifiers”, that is one of: private, protected, public. (or none.)

The purpose of access specifiers is to declare which entity can not be accessed from where. Its effect is different when used on any of: {class, class variable, class method, class's constructor}.

Access Specifiers for Class Variables and Class Methods

Here's a table showing the effects of access specifiers for class members (i.e. class variable and class methods).

Specifierclasssubclasspackageworld
privatenonono
protectedno
public
(none)nono

✅ = Can Access. No = No Access.

For example, if a variable is declared protected, then the class itself can access it, its subclass can access it, and any class in the same package can also access it, but otherwise a class cannot access it.

If a class memeber doesn't have any access specifier, its access level is sometimes known as “package”.

Here's a example.

class P {
    int x = 7;
}
public class A {
    public static void main(String[] args) {
        P p = new P();
        System.out.println(p.x);
    }
}

The code compiles and runs. But, if you add private in front of int x, then you'll get a compiler error: “x has private access in P”. This is because when a member variable is private, it can only be accessed within that class.

Access Specifiers for Constructors

Constructors can have the same access specifiers used for variables and methods. Their meaning is the same. For example, when a constructor has private declared, then, only the class itself can create a instance of it (kind of like self-reference). Other class in the same package can not create a instance of that class. Nor any subclass of that class. Nor any other class outside of this package.

(Note: constructors in Java are treated differently than methods. Class members are made of 2 things: (1) class's variables. (2) class's methods. Constructors are NOT considerd a class member.)

Here is a sample code.

class Q {
    public int x;
    private Q (int n) {
        x=n;
        System.out.println("i'm born!");
    }
}

public class A1 {
    public static void main(String[] args) {
        Q q = new Q(3);
        System.out.println(q.x);
    }
}

In the above code, it won't compile because Q's contructor is “private” but it is being created outside of itself. If you delete the “private” keyword in front of Q's constructor, then it compiles.

Constructors in Same Class Can Have Different Access Specifiers

Remember that a class can have more than one constructors, each with different parameters. Each constructor can have different access specifier.

In the following example, the class Q has two constructors, one takes a int argument, the other takes a double argument. One is declared private, while the other with no access specifier (default package level access).

class Q {
    Q (int n) {
        System.out.println("i'm born int!");
    }
    private Q (double d) {
        System.out.println("i'm born double!");
    }
}

public class A2 {
    public static void main(String[] args) {
        Q q1 = new Q(3);
        //Q q2 = new Q(3.3);
    }
}

The fact that there can be constructors with different access specifiers means that in Java, the ability to create a object also depends on which constructor is called to create the object.

Access Specifiers for Classes

For classes, only the public access specifier can be used. Basically, Java has this “One Class Per File” paradigm. That is, in every java source code file, only one class in the file is public accessible, and that class must have the same name as the file. (For Example, if the file is xyz.java, then there must be a class named “xyz” in it, and that is the class that's public.) Optionally, the class can be declared with “public” keyword.

(Note: By convention, classes names should start with capital letter. So, a class named “xyz” should be “Xyz”, with the file named “Xyz.java”.)

If you use any other access specifier on classes, or declare more than one class “public” in a file, the compiler will complain. For detail, see Packages in Java .