【问题标题】:Accessing protected member of static class in subclass of the parent在父类的子类中访问静态类的受保护成员
【发布时间】:2016-07-05 17:27:42
【问题描述】:

ExtendedDismaxQParser 类有一个静态成员类 Clause:

public class ExtendedDismaxQParser {
    protected static Class Clause {
        protected String foo, bar;
    }
    public Clause getAClause {
        Clause c;
        // misc code that isn't important
        return c;
    }
}

然后我在不同的包中扩展了这个类:

public class SpecialDismaxQParser extends ExtendedDismaxQParser {
    public void whatever() {
        Clause c = super.getAClause();
        boolean baz = c.foo.equals("foobar"); // <-- This doesn't compile
    }
}

看起来您无法访问 foo 成员变量,尽管事实上 class Clause 受到保护,并且成员变量 foo 也受到保护。

我只是希望能够检查有关受保护的静态类子句的成员变量 foo 的信息。我该怎么做(最好不反思)?

我非常希望不必修改父类,因为它是库的一部分。

【问题讨论】:

  • 这是因为 Clause 不是被扩展的类。这是一个很好的参考表:stackoverflow.com/a/33627846/276052
  • 我已经写了一个答案,但是我的互联网断了,它似乎已被删除。基本上,将字段设为public,因为它们目前仅对内部类的子类(以及同一包中的其他地方)可见。
  • 大部分分析描述的是类,而不是内部类。
  • @zelinka 但规则仍然适用。正如我所说,protected 内部类的成员只能由内部类的子类(以及包中的其他地方)访问。

标签: java static inner-classes protected


【解决方案1】:

受保护的访问修饰符只允许在包内访问变量和方法。你已经在你的 Clause 类的包中创建了你的类。

在这里反思对你没有任何好处。

【讨论】:

  • 你没有把它和包私有访问混为一谈吗?
  • 在否决投票之前只需谷歌 Java 访问修饰符
  • @rahsan 在发布错误答案之前,只需使用 Google Java 访问修饰符即可。 protected 访问也适用于子类。
  • protected 成员对子类 regardless of the package 可见。
  • @bcsb1001 我的评论没有其他建议。但是,我的评论确实指出了答案中的一个错误,即“仅在包内访问”。
【解决方案2】:

aioobe 的评论是正确的。

与外部类共享超类不足以访问静态内部类的受保护成员。

调用者的类没有扩展子句,并且在不同的包中。要使protected 具有相关性,您必须从 Clause 的子类中访问 foo,或者从与 ExtendedDismaxQParser 相同的包中的类中访问它。

【讨论】:

    【解决方案3】:

    正如 cmets 中已经说过的并且在@Nathan Hughes 的回答中很好地解释了,您无法访问Clause 中的protected 字段,因为它不是正在扩展的类。

    不幸的是,访问该字段的唯一方法是通过反射

    public class SpecialDismaxQParser extends ExtendedDismaxQParser {
        public void whatever() {
            try {
                Field fooField = Clause.class.getDeclaredField("foo");
                fooField.setAccessible(true);
                Clause c = super.getAClause();
                boolean baz = fooField.get(c).equals("foobar");
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-17
      • 2013-10-16
      • 2012-12-01
      • 2013-11-30
      • 2021-07-24
      • 2011-09-27
      • 2014-01-30
      • 2019-12-05
      相关资源
      最近更新 更多