- Details
- Written by Nam Ha Minh
- Last Updated on 18 August 2019   |   Print Email
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 > privateI hope you have learned something useful about access modifiers in Java.
Related Tutorials: Other Recommended Tutorials:
About the Author:
Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on
Facebook and watch
his Java videos on YouTube.