What is the difference between public, protected, package-private and private in Java?
Lewis D.
—In Java, any variable, class, or method can be modified with a keyword that determines its visibility to other classes. These are known as access modifiers and there are four choices (ordered from most to least restrictive): private, default (no modifier), protected, and public.
Let’s take a look at each of these access modifiers to understand the differences between them.
To explain Java access modifiers, we will reference this code example:
package example; public class NPC { private int level; boolean stuck; protected int health; public boolean alive; public NPC(int level, boolean stuck, int health, boolean alive) { this.level = level; this.stuck = stuck; this.health = health; this.alive = alive; } }
Here, our NPC
class has four properties, each with a different access modifier. Now we can extend the example to show the visibility scope for each of these.
Consider this code snippet:
import example.NPC; public class Game { public static void main(String[] args) { NPC npc = new NPC(10, false, 100, true); npc.level = 11; } }
We declared the level
property as private
in our example, so it is accessible and modifiable within the NPC
class. However, the property will not be visible to any other class. When trying to compile the above Game
class, we will get following compilation error:
Game.java:7: error: level has private access in NPC npc.level = 11; ^ 1 error error: compilation failed
Any change to the level
property must, therefore, be done within the NPC
class, like this:
package example; public class NPC { private int level; boolean stuck; protected int health; public boolean alive; public NPC(int level, boolean stuck, int health, boolean alive) { this.level = level; this.stuck = stuck; this.health = health; this.alive = alive; } public void levelUp() { this.level += 1; System.out.println("NPC is now level " + level); } }
import example.NPC; public class Game { public static void main(String[] args) { NPC npc = new NPC(10, false, 100, true); npc.levelUp(); } }
Output:
NPC is now level 11
In our code example, the stuck
property does not have an access modifier. This is the default option in Java and is also referred to as package-private.
package example; public class Wall { public void block(NPC npc) { npc.stuck = true; System.out.println("NPC is now stuck"); } }
Here, the Wall
class – which is in the same package as the NPC
class – can access and modify the stuck
property. However, as with the private access modifier, this property is not visible to classes outside of its package.
package example; public class Wall { public void block(NPC npc) { npc.stuck = true; System.out.println("NPC is now stuck"); } }
import example.*; public class Game { public static void main(String[] args) { NPC npc = new NPC(10, false, 100, true); Wall wall = new Wall(); wall.block(npc); } }
Output:
NPC is now stuck
The protected modifier is generally considered to be the most complex of the bunch. It is similar to the default modifier in that any class within the same package has access. However, the protected modifier extends visibility to any child class, even those outside the package. This is illustrated below with the health
attribute and the boss
class.
package boss; import example.NPC; public class Boss extends NPC { public Boss(int level, boolean stuck, int health, boolean alive) { super(level, stuck, health, alive); } public void bossMode() { this.health = 1000; System.out.println("Boss now has " + this.health + " health! Good Luck"); } }
import boss.Boss; public class Game { public static void main(String[] args) { Boss npc = new Boss(10, false, 100, true); npc.bossMode(); } }
Output:
Boss now has 1000 health! Good Luck
Both the default and protected access modifiers can be confusing for programmers with backgrounds in C++ or similar. In these languages, the protected
modifier restricts visibility to child classes, and the default access modifier is equivalent to the private
option in Java.
The public access modifier is more straightforward. Any class within the Java project has full access to properties or methods modified with the public access modifier. We have already been using public methods in previous examples, but let’s refer to the alive
property from the above NPC
example to make it more specific:
import example.NPC; public class Game { public static void main(String[] args) { NPC npc = new NPC(10, false, 100, true); if (npc.alive) { System.out.println("The NPC lives!"); } } }
Output:
The NPC lives!
Here’s a table to summarize visibility based on the assigned access modifier:
Private | Default | Protected | Public | |
---|---|---|---|---|
Project | X | X | X | ✓ |
Subclass different package | X | X | ✓ | ✓ |
Subclass same package | X | ✓ | ✓ | ✓ |
Class | ✓ | ✓ | ✓ | ✓ |
Tasty treats for web developers brought to you by Sentry. Get tips and tricks from Wes Bos and Scott Tolinski.
SEE EPISODESConsidered “not bad” by 4 million developers and more than 100,000 organizations worldwide, Sentry provides code-level observability to many of the world’s best-known companies like Disney, Peloton, Cloudflare, Eventbrite, Slack, Supercell, and Rockstar Games. Each month we process billions of exceptions from the most popular products on the internet.
Here’s a quick look at how Sentry handles your personal information (PII).
×We collect PII about people browsing our website, users of the Sentry service, prospective customers, and people who otherwise interact with us.
What if my PII is included in data sent to Sentry by a Sentry customer (e.g., someone using Sentry to monitor their app)? In this case you have to contact the Sentry customer (e.g., the maker of the app). We do not control the data that is sent to us through the Sentry service for the purposes of application monitoring.
Am I included?We may disclose your PII to the following type of recipients:
You may have the following rights related to your PII:
If you have any questions or concerns about your privacy at Sentry, please email us at compliance@sentry.io.
If you are a California resident, see our Supplemental notice.