Java:受保护的跨包访问
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3540640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java: protected access across packages
提问by JWhiz
I would like to understand what's happening in the example below (where a protected member is being accessed from outside the package through a subclass).
我想了解下面示例中发生的情况(通过子类从包外部访问受保护的成员)。
I know for classes outside the package, the subclass can see the protected member only through inheritance.
我知道对于包外的类,子类只能通过继承才能看到受保护的成员。
There are two packages: package1and package2.
有两个包:package1和package2。
package1:ProtectedClass.javapackage org.test.package1; public class ProtectedClass { protected void foo () { System.out.println("foo"); } }package2:ExtendsprotectedClass.javapackage org.test.package2; import org.test.package1.ProtectedClass; public class ExtendsprotectedClass extends ProtectedClass { public void boo() { foo(); // This works, // since protected method is visible through inheritance } public static void main(String[] args) { ExtendsprotectedClass epc = new ExtendsprotectedClass(); epc.foo(); // Why is this working? // Since it is accessed through a reference, // foo() should not be visible, right? } }package2:UsesExtendedClass.javapackage org.test.package2; public class UsesExtendedClass { public static void main(String[] args) { ExtendsprotectedClass epc = new ExtendsprotectedClass(); epc.foo(); // CompilationError: // The method foo() from the type ProtectedClass // is not visible } }
package1:ProtectedClass.javapackage org.test.package1; public class ProtectedClass { protected void foo () { System.out.println("foo"); } }package2:ExtendsprotectedClass.javapackage org.test.package2; import org.test.package1.ProtectedClass; public class ExtendsprotectedClass extends ProtectedClass { public void boo() { foo(); // This works, // since protected method is visible through inheritance } public static void main(String[] args) { ExtendsprotectedClass epc = new ExtendsprotectedClass(); epc.foo(); // Why is this working? // Since it is accessed through a reference, // foo() should not be visible, right? } }package2:UsesExtendedClass.javapackage org.test.package2; public class UsesExtendedClass { public static void main(String[] args) { ExtendsprotectedClass epc = new ExtendsprotectedClass(); epc.foo(); // CompilationError: // The method foo() from the type ProtectedClass // is not visible } }
It is understood that the boo()method in ExtendsprotectedClasscan access foo(), since protected members can be accessed through inheritance only.
据了解,可以访问中的boo()方法,因为受保护的成员只能通过继承访问。ExtendsprotectedClassfoo()
My question is, why is the foo()method working fine when accessed through a reference in the main()method of ExtendsprotectedClassbut will not workwhen accessed through the epcreference in UsesExtendedClass?
我的问题是,为什么foo()通过main()方法中的引用访问该方法时可以正常工作,ExtendsprotectedClass但通过 中的引用访问时却不起作用?epcUsesExtendedClass
采纳答案by Jon Skeet
Code within the ExtendsprotectedClassclass is allowed to access protected members of ProtectedClassvia a reference of type ExtendsprotectedClass. From the JLS section 6.6.2:
ExtendsprotectedClass允许类中的代码ProtectedClass通过类型的引用访问受保护的成员ExtendsprotectedClass。从JLS 部分 6.6.2:
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.
对象的受保护成员或构造函数可以从包的外部访问,在该包中仅由负责实现该对象的代码声明它。
and
和
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. [...]
设 C 是声明受保护成员 m 的类。仅允许在 C 的子类 S 的主体内访问。此外,如果 Id 表示实例字段或实例方法,则:
- 如果访问是通过限定名称 Q.Id 进行的,其中 Q 是 ExpressionName,则当且仅当表达式 Q 的类型是 S 或 S 的子类时才允许访问。 [...]
UsesExtendedClassisn't reponsible for the implementation of ExtendsprotectedClass, hence the final call fails.
UsesExtendedClass不负责 的实现ExtendsprotectedClass,因此最终调用失败。
EDIT: The reasoning behind this is that protectedaccess is designed to help subclasses implement the functionality they need, giving more access to the internals of the superclass than would normally be available. If that were available to allcode, it would be pretty close to making the method public. Basically, the subclasses are trusted not to break encapsulation; they're given more capabilities within objects of their own type. The public API shouldn't expose those details, but the protected API can just for the purposes of giving subclasses more opportunities.
编辑:这背后的原因是protected访问旨在帮助子类实现他们需要的功能,提供比通常可用的更多的超类内部访问权限。如果这对所有代码都可用,那么将非常接近公开该方法。基本上,子类被信任不会破坏封装;他们在自己类型的对象中被赋予了更多的能力。公共 API 不应该公开这些细节,但受保护的 API 可以只是为了给子类更多机会。
回答by fastcodejava
It is working in the first case because it is being called from the same class even the method is being accessed through a reference. You could even call a privatemethod of ExtendsprotectedClassthrough a reference in the same main method.
它在第一种情况下工作,因为它是从同一个类调用的,即使该方法是通过引用访问的。您甚至可以在同一个主方法private中ExtendsprotectedClass通过引用调用方法。
回答by Michael Aaron Safyan
I believe you've answered your own question; UsesExtendedClass does not inherit from ProtectedClass, and -- by definition -- "protected" members are accessible only in the class in which they are declared / defined or in a class that inherits from the one in which they are declared or defined.
我相信你已经回答了你自己的问题;UsesExtendedClass 不从 ProtectedClass 继承,并且——根据定义——“受保护”成员只能在声明/定义它们的类中或在继承自它们声明或定义的类的类中访问。
回答by Maher Abuthraa
take a look on this picture from : http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
看看这张图片来自:http: //docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html


its clear that protected member of class can be accessed via subclass.
很明显,可以通过子类访问类的受保护成员。

