Categories
access-modifiers java private protected public

What is the difference between public, protected, package-private and private in Java?

3520

In Java, are there clear rules on when to use each of access modifiers, namely the default (package private), public, protected and private, while making class and interface and dealing with inheritance?

18

  • 183

    private hides from other classes within the package. public exposes to classes outside the package. protected is a version of public restricted only to subclasses.

    – Museful

    Feb 13, 2013 at 9:56


  • 102

    @Tennenrishin — No ; contrary to C++, in Java protected makes the method also accessible from the whole package. This stupidity in Java’s visiblity model breaks the goal of protected.

    Aug 21, 2013 at 9:51

  • 40

    @Nicolas It is accessible from the whole package, with or without protected. As an access modifier, all that protected does is to expose to subclasses outside the package.

    – Museful

    Mar 14, 2014 at 10:59


  • 17

    @tennenrishin – well, that is what Nicolas said… and you are just repeating it now. What you originally said was that protected – and I quote – ‘is a version of public restricted only to subclasses’ which is not true by your own admission since protected also allows access through the whole package (ergo, it does not restrict access to subclasses.)

    Apr 7, 2014 at 13:45


  • 14

    I also agree with Nicolas in that the protected access mode in Java is idiotic. What happened is that Java conflated horizontal (lattice) and vertical access restriction qualifiers. Default scope is a horizontal/lattice restriction with the lattice being the package. Public is another horizontal restriction where the lattice is the whole world. Private and (C++) protected are vertical. It would have been better if we had a cross-cut access, say, protected-package for the rare cases where we actually needed it, leaving protected to be equivalent to the C++ version of protected.

    Apr 7, 2014 at 13:53

6152

The official tutorial may be of some use to you.


ClassPackageSubclass
(same pkg)
Subclass
(diff pkg)
World
public+++++
protected++++
no modifier+++
private+

+ : accessible
blank : not accessible

19

  • 9

    World is within your project. I should explain further. Libraries are within your project, and if you’re creating a library, they would expose these public classes and methods as well. So, saying just within your project is a bit off. “Everything that uses it” is a better description.

    – adprocas

    May 3, 2018 at 13:02

  • 7

    For example, if I have MyClass and I’m doing AnotherClass extends MyClass I will have access to all protected and public methods and properties from within AnotherClass. If I do MyClass myClass = new MyClass(); in AnotherClass somewhere – let’s say the constructor – I will only have access to the public methods if it is in a different package. Note that if I do = new MyClass() { @Override protected void protectedMethod() { //some logic } }; it appears that I can access protected methods, but this kind of the same as extending it, but inline instead.

    – adprocas

    May 4, 2018 at 12:25

  • 9

    Unfortunately, this answer is a gross oversimplification. Reality is a bit more complicated, especially when you consider protected (which is actually quite a difficult access modifier to fully understand – most people who think they know what protected means really don’t). Also, as Bohemian pointed out, it doesn’t answer the question – it says nothing about when to use each access modifier. In my opinion, this answer isn’t quite bad enough to downvote, but close. But over 4000 upvotes? How did this happen?

    Jul 11, 2018 at 6:26

  • 19

    @niks protected members CAN be accessed by subclasses from a different package. Isn’t that the point? Otherwise what’s the difference between default and protected?

    – Jack

    Oct 15, 2020 at 12:30


  • 8

    @Jack Yeah, niks’ comment is wrong despite the many upvotes stating otherwise. The Java Tutorials link in the answer clearly says that protected members can also be accessed within subclasses from a different package. It seems that he/she meant “package-level” instead of “protected”, or was referring to a different edit.

    – Piovezan

    Feb 5, 2021 at 2:57


526

(Caveat: I am not a Java programmer, I am a Perl programmer. Perl has no formal protections which is perhaps why I understand the problem so well 🙂 )

Private

Like you’d think, only the class in which it is declared can see it.

Package Private

It can only be seen and used by the package in which it was declared. This is the default in Java (which some see as a mistake).

Protected

Package Private + can be seen by subclasses or package members.

Public

Everyone can see it.

Published

Visible outside the code I control. (While not Java syntax, it is important for this discussion).

C++ defines an additional level called “friend” and the less you know about that the better.

When should you use what? The whole idea is encapsulation to hide information. As much as possible you want to hide the detail of how something is done from your users. Why? Because then you can change them later and not break anybody’s code. This lets you optimize, refactor, redesign, and fix bugs without worrying that someone was using that code you just overhauled.

So, the rule of thumb is to make things only as visible as they have to be. Start with private and only add more visibility as needed. Only make public that which is necessary for the user to know, every detail you make public cramps your ability to redesign the system.

If you want users to be able to customize behaviors, rather than making internals public so they can override them, it’s often a better idea to shove those guts into an object and make that interface public. That way they can simply plug in a new object. For example, if you were writing a CD player and wanted the “go find info about this CD” bit customizable, rather than make those methods public you’d put all that functionality into its object and make just your object getter/setter public. In this way being stingy about exposing your guts encourages good composition and separation of concerns

I stick with just “private” and “public”. Many OO languages just have that. “Protected” can be handy, but it’s a cheat. Once an interface is more than private it’s outside of your control and you have to go looking in other people’s code to find uses.

This is where the idea of “published” comes in. Changing an interface (refactoring it) requires that you find all the code which is using it and change that, too. If the interface is private, well no problem. If it’s protected you have to go find all your subclasses. If it’s public you have to go find all the code which uses your code. Sometimes this is possible, for example, if you’re working on corporate code that’s for internal use only it doesn’t matter if an interface is public. You can grab all the code out of the corporate repository. But if an interface is “published”, if there is code using it outside your control, then you’re hosed. You must support that interface or risk breaking code. Even protected interfaces can be considered published (which is why I don’t bother with protected).

Many languages find the hierarchical nature of public/protected/private to be too limiting and not in line with reality. To that end, there is the concept of a trait class, but that’s another show.

8

  • 27

    friends -> “The less you know about it the better” —> It gives selective visibility, which is still superior to package privacy. In C++, it has its uses, because not all functions can be member functions, and friends is better than public’ing. Of course there is a danger of misuse by evil minds.

    Jun 7, 2011 at 10:13


  • 33

    It should also be noted that “protected” in C++ has a different meaning – a protected method is effectively private, but can still be called from an inheriting class. (As opposed to Java where it can be called by any class within the same package.)

    Oct 2, 2011 at 12:34

  • 9

    @RhysvanderWaerden C# is the same as C++ in this aspect. I find it pretty odd that Java doesn’t allow to declare a member that’s accessible to the subclass but not the entire package. It’s sort of upside down to me – a package is broader scope than a child class!

    Oct 15, 2013 at 17:36


  • 15

    @KonradMorawski IMHO package is smaller scope than subclass. If you haven’t declared your class final, users should be able to subclass it – so java protected is part of your published interface. OTOH, packages are implicitly developed by a single organization: e.g. com.mycompany.mypackage. If your code declares itself in my package, you implicitly declare yourself part of my organization, so we should be communicating. Thus, package publishes to a smaller/easier to reach audience (people in my company) than subclass (people who extend my object) and so counts as lower visibility.

    – Eponymous

    May 22, 2014 at 20:37


  • 2

    friend is good for defining special relationships between classes. It allows superior encapsulation in many cases when used correctly. For example it can be used by a privileged factory class to inject internal dependencies into a constructed type. It has a bad name because people who don’t care about correctly maintaining a well designed object model can abuse it to ease their workload.

    – Dennis

    Dec 8, 2014 at 10:05

502

Here’s a better version of the table, that also includes a column for modules.

enter image description here


Explanations

  • A private member (i) is only accessible within the same class as it is declared.

  • A member with no access modifier (j) is only accessible within classes in the same package.

  • A protected member (k) is accessible within all classes in the same package and within subclasses in other packages.

  • A public member (l) is accessible to all classes (unless it resides in a module that does not export the package it is declared in).


Which modifier to choose?

Access modifiers is a tool to help you to prevent accidentally breaking encapsulation(*). Ask yourself if you intend the member to be something that’s internal to the class, package, class hierarchy or not internal at all, and choose access level accordingly.

Examples:

  • A field long internalCounter should probably be private since it’s mutable and an implementation detail.
  • A class that should only be instantiated in a factory class (in the same package) should have a package restricted constructor, since it shouldn’t be possible to call it directly from outside the package.
  • An internal void beforeRender() method called right before rendering and used as a hook in subclasses should be protected.
  • A void saveGame(File dst) method which is called from the GUI code should be public.

(*) What is Encapsulation exactly?

7

  • 22

    Just saying: there are a lot of people who have problems with distinguishing red/green coloring. Tables using red/green (or yellow/orange/…) coloring schemes are rarely “better” at anything 😉

    – GhostCat

    Oct 11, 2018 at 10:50


  • 7

    @GhostCat, I disagree. I think red/green aligns intuitively with “works”/”does not work” for many people, i.e. it is better than many alternatives.

    – aioobe

    Nov 14, 2018 at 14:10

  • 12

    colourblindawareness.org/colour-blindness/…The 8% of colour blind men can be divided approximately into 1% deuteranopes, 1% protanopes, 1% protanomalous and 5% deuteranomalous. And as I am one of those 50% of that 5%, rest assured: red/green sucks.

    – GhostCat

    Nov 14, 2018 at 14:13


  • 7

    @GhostCat Ok.. that’s a larger part of the population than I expected. I uploaded the image in this color blindness simulator and tested all different modes. Even in monochromacy/achromatopsia mode the color difference is reasonable. Can you see the difference or is the simulator off? (I’m still of the opinion that red/green is very intuitive for color seeing people.)

    – aioobe

    Nov 14, 2018 at 14:32


  • 5

    I can see the difference, but I am also able to pass half of the color blindness tests that we have to do in Germany for the drivers licence 😉 … but I think such a simulator is “good enough”.

    – GhostCat

    Nov 14, 2018 at 14:40