在父类的子类中访问静态类的受保护成员

Posted

技术标签:

【中文标题】在父类的子类中访问静态类的受保护成员【英文标题】: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 不是被扩展的类。这是一个很好的参考表:***.com/a/33627846/276052 看看***.com/questions/14534421/…。 我已经写了一个答案,但是我的互联网断了,它似乎已被删除。基本上,将字段设为public,因为它们目前仅对内部类的子类(以及同一包中的其他地方)可见。 大部分分析描述的是类,而不是内部类。 @zelinka 但规则仍然适用。正如我所说,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();
        
    

【讨论】:

以上是关于在父类的子类中访问静态类的受保护成员的主要内容,如果未能解决你的问题,请参考以下文章

我们可以在父类的帮助下访问不同包中的受保护变量吗?

java中私有的属性、静态成员可以被子类继承吗?

访问另一个子类中基类的受保护成员

如何在同一个类的静态方法中访问类的受保护变量?

子类继承父类怎么在父类的方法中访问子类的变量

Java中类变量可以被继承吗