Difference Between Public, Protected, Package-Private and Private in Java

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

The official tutorial may be of some use to you.

















































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

difference between protected and package-private access modifiers in Java?

The first answer is basically correct - protected members can be accessed by

  • classes from the same package
  • subclasses of the declaring class from other packages

However, there is a little trick:

6.6.2 Details on protected Access

A protected member or constructor of an object may be accessed from outside the package in which it is declared only by code that is responsible for the implementation of that object.

It means that subclass from other package cannot access protected members of arbitrary instances of their superclasses, they can only access them on instances of their own type (where type is a compile-time type of expression, since it's a compile-time check).

For example (assuming that this code is in Cat):

Dog dog = new Dog();
Animal cat = new Cat();

dog.testInstanceMethod(); // Not allowed, because Cat should not be able to access protected members of Dog
cat.testInstanceMethod(); // Not allowed, because compiler doesn't know that runtime type of cat is Cat

((Cat) cat).testInstanceMethod(); // Allowed

It makes sense, because accessing of protected members of Dog by Cat may break invariants of Dog, whereas Cat can access its own protected members safely, because it knows how to ensure its own invariants.

Detailed rules:

6.6.2.1 Access to a protected Member

Let C be the class in which a protected member m is declared. Access is permitted only within the body of a subclass S of C. In addition, if Id denotes an instance field or instance method, then:

  • If the access is by a qualified name Q.Id, where Q is an ExpressionName, then the access is permitted if and only if the type of the expression Q is S or a subclass of S.
  • If the access is by a field access expression E.Id, where E is a Primary expression, or by a method invocation expression E.Id(. . .), where E is a Primary expression, then the access is permitted if and only if the type of E is S or a subclass of S.

6.6.2.2 Qualified Access to a protected Constructor

Let C be the class in which a protected constructor is declared and let S be the innermost class in whose declaration the use of the protected constructor occurs. Then:

  • If the access is by a superclass constructor invocation super(. . .) or by a qualified superclass constructor invocation of the form E.super(. . .), where E is a Primary expression, then the access is permitted.
  • If the access is by an anonymous class instance creation expression of the form new C(. . .){...} or by a qualified class instance creation expression of the form E.new C(. . .){...}, where E is a Primary expression, then the access is permitted.
  • Otherwise, if the access is by a simple class instance creation expression of the form new C(. . .) or by a qualified class instance creation expression of the form E.new C(. . .), where E is a Primary expression, then the access is not permitted. A protected constructor can be accessed by a class instance creation expression (that does not declare an anonymous class) only from within the package in which it is defined.

See also:

  • Java Language Specification

When to use Package-Private or Protected

Use protected whenever you think only classes that extend should have access. Use package private whenever you think only classes that are from the same package should have access. Honestly, I’ve only used package private for inner classes.

What are public, private and protected in object oriented programming?

They are access modifiers and help us implement Encapsulation (or information hiding). They tell the compiler which other classes should have access to the field or method being defined.

private - Only the current class will have access to the field or method.

protected - Only the current class and subclasses (and sometimes also same-package classes) of this class will have access to the field or method.

public - Any class can refer to the field or call the method.

This assumes these keywords are used as part of a field or method declaration within a class definition.

How does Java protect private, package-private, and protected variables?

Visibility scoping is implemented in two places in Java: in the compiler and in the JVM that executes the bytecode.

First, the compiler limits visibility of variables flagged with public, protected and private keywords (also note that Java has a fourth scope, called the default scope, that was what you get when you declare a variable without one of the three keywords). The differences are documented elsewhere (see In Java, difference between default, public, protected, and private or any good books on Java programming).

Second, and I think this is more what you are asking about, is that Java protects access to variables with private, protected and the default scope within the JVM at runtime. This primarily applies to Java's reflection API (if your non-reflection code compiles you know it isn't accessing anything it isn't allowed to access and thus can't run into runtime visibility problems). For example, say you've got this in Foo.java:

// class with a private member variable
public class Foo {
private int bar = 0;
}

And then you try to access bar from another class using reflection in Test.java:

import java.lang.reflect.*;

// This class won't have access to Foo's member 'bar'
public class Test {

void doStuff() {
// create a new instance of Foo
Foo foo = new Foo();
try {
// use reflection to get the variable named 'bar'
Field barField = foo.getClass().getDeclaredField("bar");

// attempt to access the value of 'bar' which will throw an exception
System.out.println(barField.get(foo));

} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}

public static void main(String[] args) {
new Test().doStuff();
}

}

You would get an exception indicating you have no access to that variable. There are ways to circumvent this, but the point here is that by default the JVM protects access to variables (and methods and classes) outside the scope you'd normally be able to see.

Addendum

Java doesn't typically "hide" anything since it doesn't need to. Neither the Java language nor the JVM bytecode have access to the pointers used behind the scenes and there's also no other way through the language or the reflection API to access arbitrary locations in memory and thus no way (with one exception -- see below) to read the value of a variable to which you don't have access. When using reflection the JVM simply checks a flag (initially set by the compiler) to see if the current code has access to the variable or method being accessed and then either allows the access or throws an exception.

The exception I mentioned is a reflection API call that can turn off the access checking for a given variable or method. For example, to avoid the exception from my previous example you could do this:

...
Field barField = foo.getClass().getDeclaredField("bar");
// mark the variable 'bar' as accessible
barField.setAccessible(true);
// attempt to access the value of 'bar' which will throw an exception
System.out.println(barField.get(foo));
...

Pros and cons of package private classes in Java?

The short answer is - it's a slightly wider form of private.

I'll assume that you're familiar with the distinction between public and private, and why it's generally good practice to make methods and variables private if they're going to be used solely internally to the class in question.

Well, as an extension to that - if you're thinking about creating your software in a modular way, you might think about a public interface to your module, which will have multiple classes inside it collaborating between themselves. In this context it makes perfect sense to make methods public if they're going to be called by consumers; private if they're internal to a class; and package private if they're used to call between classes in this module, i.e. it's an implementation detail of your module (as seen by public callers) but spans several classes.

This is seldom used in practice, because the package system turns out to not be so useful for this sort of thing. You'd have to dump all of the classes for a given module into exactly the same package, which for anything non-trivial is going to get a bit unwieldy. So the idea is great - make a method accessible to just a handful of "nearby" classes, as a slightly wider private - but the restrictions on how you define that set of classes means it's rarely used/useful.

what is diffrence between private access modifier and no access modifier in java?

private - Only the class itself can access it

package-private - No modifier is assigned. Only classes in the same package can access it

Isn't package private member access synonymous with the default (no-modifier) access?

Yes, it's almost the same. The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package.



Related Topics



Leave a reply



Submit