Java is one of the most popular languages today. It was designed by James Gosling. It is general-purpose, class-based and object-orientated.

With java, one of the first things that comes to mind — apart from coffee — is the daunting list of keywords used before different java components like classes, interfaces and methods. In this post, I’ll discuss 4 of those keywords — called access modifiers.

The 4 access modifiers used in java are:

  • public
  • protected
  • default
  • private

First let me define an access modifier. An access modifier when applied on an a java component like a class modifies the accessibility of that component. Different access modifiers allow for different “visibility” types. In some places, access modifiers are also referred to as access specifiers, though the official documentation sticks to the former.

Moving on to the different kinds of modifiers…

$ \ $

Private

This is the access modifier with the least visibility. Class members with this modifier can only be accessed within that class and nowhere else.

This is the reason why interfaces and classes can’t be private. It would be impossible to work with a private class or interface.

Example

class PrivateNumber
{
	private int x;
}
class Test
{
	public static void main(String[] args)
	{
		PrivateNumber num = new PrivateNumber();
		System.out.println(num.x);
	}
}

Output

:~$ javac Test.java
Test.java:11: error: x has private access in PrivateNumber
		System.out.println(num.x);
		                      ^
1 error

Solution
Use a getter method which returns the value of x

class PrivateNumber
{
	private int x;
	
	public int getx()
	{
		return x;
	}
}
class Test
{
	public static void main(String[] args)
	{
		PrivateNumber num = new PrivateNumber();
		System.out.println(num.getx());
	}
}

The output:

$ java Test
0

Again, this is for regular classes. Nested classes are allowed to have the private and protected keyword.

Coming to constructors, they can have private visibility. Constructors are used for creating an object and assigning its reference to an object reference variable. If a constructor is private, it would logically mean that it won’t be possible to create an object of that class outside of it.

$ \ $

Example

class Example
{
	int x;
	private Example(int x)
	{
		this.x = x;
	}
}
class Test
{
	public static void main(String[] args)
	{
		Example ex = new Example(3);
		System.out.println(ex.x);
	}
}

output

:~$ java Test.java
Test.java:14: error: Example(int) has private access in Example
		Example ex = new Example(3);
		             ^
1 error

Solution

class Example
{
	int x;
	private Example(int x)
	{
		this.x = x;
	}
	public static void main(String[] args)
	{
		Example ex = new Example(3);
		System.out.println(ex.x);
	}
}
:~$ javac Example.java
:~$ java Example
	3


$ \ $

Default

The next one is the default access modifier. As the name suggests, this is the default modifier applied to java components when nothing has been explicitly mentioned. The visiblity of this is slightly more than that of the private keyword in that even other classes in the same package can access these components. This visibility does not extend to the child or sub classes of that class when that subclass resides in another package.

Example

package a;

class Parent
{
	int x;
}
package b;

import a.*;
class Child extends Parent
{
	public static void main(String[] args)
	{
		// since x is not static:
		Child c = new Child();
		System.out.println(c.x);
	}
}

Running the code:

:~$ javac -d . Parent.java
:~$ javac -d . Child.java

Child.java:3: error: Parent is not public in a; cannot be accessed from outside package
import a.Parent;
        ^
Child.java:5: error: Parent is not public in a; cannot be accessed from outside package
class Child extends Parent
                    ^
Child.java:9: error: cannot find symbol
		System.out.println(c.x);
		                   ^
  symbol:   variable x
  location: class Child
3 errors

The above error is due to the fact that default classes (when no keyword is mentioned, its considered default) cannot be accessed outside that package.

Now, if we make the Parent class public, lets see what happens:

:~$ javac -d . Parent.java
:~$ javac -d . Child.java
Child.java:9: error: x is not public in Parent; cannot be accessed from outside package
		System.out.println(c.x);
		                   ^
1 error

Thus, to be able to access x, the protected keyword must be used.


$ \ $

Protected

The protected keyword is quite similar to default in terms of visibility. The only difference being that even subclasses can access the parent class’ protected members even when those subclasses are present in another package.

Example

Lets consider the above example again:

package a;

public class Parent
{
	protected int x;
}
package b;

import a.*;
class Child extends Parent
{
	public static void main(String[] args)
	{
		// since x is not static:
		Child c = new Child();
		System.out.println(c.x);
	}
}

And the output

:~$ javac -d . Parent.java
:~$ javac -d . Child.java
:~$ java b.Child  
0

$ \ $

Public

Aptly named, this keyword can be used by all components of java — classes, interfaces, constructors, variables but not blocks. Any class can access such components, even if it exist in another package. This keyword also supports inheritance.


To summarise

$ \ $

I end this post here. I hope I was clear and accurate in my explanation.