了解java的受保护的修饰符

我在package1中有一个名为A的类,在package2中有一个名为C的类。 C类扩展了A类

A有一个实例变量是这样声明的:

protected int protectedInt = 1; 

这是A类的代码

 package package1; public class A { public int publicInt = 1; private int privateInt = 1; int defaultInt = 1; protected int protectedInt = 1; } 

这里是C类的代码:

 package package2; import package1.A; public class C extends A{ public void go(){ //remember the import statement A a = new A(); System.out.println(a.publicInt); System.out.println(a.protectedInt); } } 

Eclipse强调了C.go()中的最后一行,并说“A.protectedInt”不可见。 看来这与oracle文档中给出的“protected”关键字的定义相冲突。

受保护的修饰符指定该成员只能在其自己的包内访问(与包私有一样),另外还可以在另一个包中访问该类的子类。

这里发生了什么?

这里发生了什么?

你误解了protected的含义。 您可以从C访问在A声明的受保护成员,但只能访问CC子类的实例。 有关受保护访问的详细信息,请参阅JLS的第6.6.2节 。 尤其是:

设C是声明受保护成员的类。 只有在C的子类S中才允许访问

另外,如果Id表示实例字段或实例方法,则:

  • […]

  • 如果通过字段访问表达式E.Id(其中E是主表达式)或通过方法调用表达式E.Id(…)(其中E是主表达式)来访问,则只有当且仅当如果E的类型是S或S的一个子类

(强调我的)

所以这段代码会很好:

 C c = new C(); System.out.println(c.publicInt); System.out.println(c.protectedInt); 

由于C继承了AC可以直接使用下面的Aprotected变量

 public class C extends A{ public void go(){ System.out.println(protectedInt); } } 

根据你的代码,你正在创建一个A的实例,并通过该实例访问protected变量,这违反了Java的规则 – 一个受保护的变量在包之外是不可见的

  public void go(){ //remember the import statement A a = new A(); System.out.println(a.publicInt); System.out.println(a.protectedInt); } 

当你正在做A a = new A();a.protectedInt你试图访问A的保护成员是非法的,根据Java标准

相反,你可以直接做this.protectedInt

不需要在Protection2 Class中实例化Protection类。 您可以直接调用受保护的变量而不用实例化Protection类。 由于Protection2类扩展了Protection类。 所以变量自动被子类继承。

试试下面的代码:

 public class Protection2 extends Protection{ Protection2() {System.out.println("n_pro = " +n_pro); }} 

在声明受保护成员的相同包中,允许访问:

 package package1; public class C extends A{ public void go(){ A a = new A(); System.out.println(a.protectedInt); // got printed C c = new C(); System.out.println(c.protectedInt); // got printed as well } } 

在声明受保护成员的包之外,当且仅当通过负责实现该对象的代码才允许访问。 在这种情况下,C负责实现该对象,因此它可以访问受保护的对象。

 package package2; public class C extends A{ public void go(){ A a = new A(); System.out.println(a.protectedInt); // compiler complains C c = new C(); System.out.println(c.protectedInt); // got printed } }