【问题标题】:Protected Access Modifier受保护的访问修饰符
【发布时间】:2013-03-05 21:21:16
【问题描述】:

我有以下两段代码:

/**
 * 
 */
package com.akshu.multithreading;

/**
 * @author akshu
 *
 */
public class MyThread extends Thread {
    protected  int b;   

    private int a;
    @Override
    public void run() {

        super.run();

        System.out.println("int a:"+a);
    }

}



-----------


package com.akshu.utility;

import com.akshu.multithreading.MyThread;

public class MyUtility extends MyThread{

    public static void main(String args[])
    {
        MyThread th1 = new MyThread();
        int d =th1.b;  // line1
        System.out.println("int d"+d);
    }

}

通过上面的代码文件,我试图了解受保护的访问修饰符的目的。在文件 MyUtility 中,我试图引用 MyThread 类的变量 b。但它给了我以下错误:

Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
    The field MyThread.b is not visibilty.

我担心变量 b 应该可以从子类访问,因为我已经扩展了 Mythread。但它给了我编译时错误。此外,当我在我的超类中将此变量声明为静态时,我能够直接访问它。那么当我尝试通过实例访问时,我做错了什么?

【问题讨论】:

    标签: java variables protected


    【解决方案1】:

    方法 main 不是 MyThread 的明确部分 - 如果您要实现另一个函数,例如printtB(),您可以使用带有“.”的直接访问。操作员。要从 main 访问它,您必须编写一个 getter 函数。

    【讨论】:

      【解决方案2】:

      您无法从实例访问受保护的属性。您只能在继承类中访问它们。在这一行——

      MyThread  th1  = new MyThread (); int  d  = th1 . b ;
      

      您实际上是在尝试从实例 th1 访问受保护的属性。

      【讨论】:

      • OP 实际上是在尝试从实例 th1 访问受保护的属性。
      • :谢谢,我明白了。我将两种不同的可见性混合在一起。一个用于实例,另一个用于继承。
      【解决方案3】:

      来自Kathy Sierra's的好书,解释protected作用域的误区:

      但是对于包外的子类来说,这意味着什么 访问超类(父)成员?这意味着子类继承 该成员。然而,这并不意味着 subclass-outside-the-package 可以使用引用访问成员 到超类的一个实例。换句话说,受保护 = 遗产。受保护并不意味着子类可以对待 保护超类成员,就好像它是公共的一样。所以如果 subclass-outside-the-package 获取对超类的引用(通过, 例如,在某处创建超类的实例 子类的代码),子类不能在 访问受保护成员的超类引用。到一个 包外的子类,受保护的成员也可能是 默认(甚至私有),当子类使用对 超类。 子类只能通过 继承。

      因此,在您的情况下,您尝试使用引用来访问父类包之外的受保护成员:

      MyThread th1 = new MyThread();
      int d =th1.b;  //b cannot be reached !
      

      【讨论】:

        【解决方案4】:

        Java 语言规范第 6.6.2.1 节将告诉你真相:

        如果通过字段访问表达式E.Id(其中E 是主表达式)或通过方法调用表达式E.Id(. . .)(其中E 是主表达式)进行访问,则允许访问,如果并且仅当 E 的类型是 SS 的子类时。

        这里MyThreadCMyUtilityS,b 是Id。因此,在 MyUtility iontance 中,您不能使用对实例 pf MyThread 的引用来访问其 b

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-05-07
          • 2014-12-29
          • 2013-04-03
          • 2015-02-11
          • 1970-01-01
          • 2016-04-03
          相关资源
          最近更新 更多