Do you see some keywords like public, private and protected in Java code?

Do you see these words somewhat confusing? Sometimes they are used before a class, a field, a constructor and method. What do they mean actually?

Don’t worry, as in this tutorial I will reveal everything about these so-called access modifiers in Java. Sometimes they are called access specifiers or access visibility - all has same meaning.

Let’s start!

 

1. What are access modifiers in Java?

In Java, the term access modifiers refer to the keywords which are used to control accessibility to classes, interfaces, fields, constructors and methods. That means we can determine what can access our code. For example, if we want our Dog class can be accessed everywhere, use the public modifier:

public class Dog { }
There are two types of access modifiers:

  • Top-level access modifiers: publicand default (default is when no access modifier is used). These access modifiers apply to types only (classes, interfaces, enums and annotations).  

  • Member-level access modifiers: public, protected, default and private. These access modifiers apply to fields, constructors and methods.
So we can see, there are 4 different access modifiers: public, protected, default and private. They are applied for members of a type. The protected and private modifiers cannot be applied for types (classes, interfaces,…). I will explain the meaning of each modifier shortly. So read on.



 

2. Why are access modifiers?

Access modifiers are used to control the accessibility to classes, interfaces, fields, constructors and methods. In other words, we can use access modifiers to protect data and behaviors from the outside world. At a high level, access modifiers facilitate the encapsulation feature in Object-Oriented Programming.

They are the core, fundamental and important concepts in Java which you have to grasp a deep understanding in order to write code properly, efficiently, securely an professionally.

 

3. How do access modifiers work?

In this section, I explain the meaning and usage of each access modifier in Java. Here’s the order of the access modifiers from the least restrictive to the most restrictive:

                public > protected > default > private

 

Java public access modifier:

When applied to a class, the class is accessible from any classes regardless of packages. This is the least restrictive access modifier which means the widest range of accessibility, or visibility.

When applied to a member, the member is accessible from any classes.

The following example shows two classes in different packages:

The Dog class:

package animal;

public class Dog {
	public String name;

	public void bark() {
		System.out.print("Gow Gow!");
	}
}
 

The Trainer class:

package training;

import animal.Dog;

public class Trainer {
	public void teach(Dog dog) {
		dog.name = "Rex";
		dog.bark();
	}
}
 

Here, the Dogand Trainer classes are in 2 different packages: animal and training, respectively. Because the Dog class is declared as public, and also its member name field and bark() method, the Trainer class can invoke them:

dog.name = "Rex";
dog.bark();
 

Java protected access modifier:

This is more restrictive than the public modifier. It is applied for members only. There is no ‘protected’ class or interface.

When a member of a class is marked as protected, it is accessible by only classes in the same package or by a subclass in different package. Let’s see three examples to understand how this modifier works.

 

protected access modifier example #1:

The Person class:

package human;

import animal.Dog;

public class Person {
	public void play() {
		Dog dog = new Dog();
		dog.waveTail();	// COMPILE ERROR!
	}
}
 

The Dog class:

package animal;

public class Dog {
	protected void waveTail() {
		System.out.print("Waving my tail...");
	}
}
Here, the Person and Dog classes are in 2 different packages. The waveTail() method of the Dog class is protected, thus the Person class cannot invoke it:

dog.waveTail();	// COMPILE ERROR: waveTail() has protected access in Dog
 

protected access modifier example #2:

Suppose Hound is a subclass of Dog:

package hunt;

public class Hound extends Dog {
	public void play() {
		super.waveTail();
	}
}
Here, although Hound is in different package but it is a subclass of Dog, hence it is allowed to invoked the protected method waveTail() from its parent.

 

protected access modifier example #3:

Suppose Cat is a class which is in the same package with the Dog class above. Therefore, Cat is eligible to invoke a protected member of Dog:

package animal;

public class Cat {
	public void playWith(Dog dog) {
		dog.waveTail();
	}
}
 

Java default access modifier:

This access modifier is special because it doesn’t have an associated keyword. When no explicit access modifier is specified, the types or members have default accessibility. It is more restrictive than the protected modifier.

When a class or a member has default accessibility, it is accessible to only classes in the same package. For example:

The Wolf class:

package animal;

class Wolf {
	public void play() {

	}
}
 

The Person class:

package human;

import animal.Wolf;

public class Person {
	public void hunt() {
		Wolf wolf = new Wolf();	// COMPILE ERROR
	}
}
Here, because the Wolf class has default accessibility, the Person class (in different package) cannot create new instance of it. The compiler issues an error: cannot find symbol.

But the Dog class in the same package is able to access:

package animal;

public class Dog {
	public String name;
	public void hunt() {
		Wolf wolf = new Wolf(); 	// Okay
	}
}
 

Java private access modifier:

This is the most restrictive access modifier in Java. It can be applied for members only. There is no ‘private’ class or interface (except nested classes and interfaces which I will cover later in this course).

When a member is marked as private, it is only accessible from within the enclosing class. Nothing outside the class can access a private member. Here’s an example:

The Dog class:

package animal;

public class Dog {

	private String breed;

	public Dog() {
		breed = "Bull";
	}
}
 

The Trainer class:

package training;

import animal.Dog;

public class Trainer {
	public void teach(Dog dog) {
		dog.breed = "Wolf";	// COMPILE ERROR
	}
}
Here, the Dog class declares the field breed as private. Hence the breed variable is accessible only within its class, e.g. in the constructor. Whereas the Trainer class attempts to access this field causing a compile error: breed has private access in Dog.

Okay, so far you understood how the access modifiers work in Java. You may ask: When to use which access modifier?

The answer is it depends on your own need and situation. But the rule of thumb is that, always apply the most restrictive access modifier unless you have reasons to use the less restrictive ones. For example, all fields in a class should be private by default, and all the behaviors are public.

NOTE: local variables (within a method body) do not have access modifiers because they are accessible only within the method itself.

To summary, remember the order of access modifiers from the least restrictive to the most restrictive:

                public > protected > default > private

I hope you have learned something useful about access modifiers in Java.

 

Related Tutorials:

 

Other Recommended Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.



Add comment

   


Comments 

#6Nam2018-06-12 10:10
Quoting shylaja:
in Public modifier example thare is no object created for the Dog class in trainer. without object creation how dog.bark() will get invoked?

The Trainer's teach(Dog dog) takes a parameter of type Dog - so the caller code must pass a Dog object when invoking this method.
Quote
#5Nam2018-06-12 10:05
Quoting secret:
"Here, although Hound is in different package but it is a subclass of Dog, hence it is allowed to invoked the protected method waveTail() from its parent."
I think Hound is not in different package with Dog, they are together in package animal?

Good catch! It was a mistake. Fixed. Thank you very much.
Quote
#4secret2018-06-11 21:19
"Here, although Hound is in different package but it is a subclass of Dog, hence it is allowed to invoked the protected method waveTail() from its parent."
I think Hound is not in different package with Dog, they are together in package animal?
Quote
#3shylaja2017-05-06 10:49
in Public modifier example thare is no object created for the Dog class in trainer. without object creation how dog.bark() will get invoked?
Quote
#2Douglas2017-04-07 02:42
Very Nice notes and easy to understand,Thank you so much.God bless you for your good work.
Quote