Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
663 views
in Technique[技术] by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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:


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...