静态方法使用protected修饰符的目的是什么?

12

在寻找我的另一个问题的解决方案时,我发现了protected修饰符的这种用法:Ignoring case in strings with unitils ReflectionComparator

org.unitils.reflectionassert.ReflectionComparatorFactory类中有一个带有如下签名的方法:

protected static List<Comparator> getComparatorChain(Set<ReflectionComparatorMode> modes)

但这只是一个特例。

毕竟我们始终可以扩展任何非最终类,并将其静态的protected方法用新的public修饰符进行“覆盖”。 假设我们有一个类A

public class A {
    protected static void test() {
        // do some stuff
    }
}

并且希望在另一个软件包中使用它:

public class UseA {
    private static class MyA extends A {
        public static void test() {
            A.test();
        }
    }

    void useA() {
        // A.test(); compile error, sure
        MyA.test();
    }
}

我将重点关注一般情况下某些static方法被声明为protected的情况。我不是在问非静态字段或方法,因为在某些情况下,类可以有一个私有构造函数或包含许多特殊参数的非常复杂的构造函数。但如果整个类不是final,那么这种“隐藏”静态方法的目的是什么?这种用法是面向对象编程(OOP)的错误,还是只是一种非常薄弱的“保护”?


2
你不能覆盖静态方法。你只能在子类中重新定义它们。 - Chetan Kinger
1
@bot 当然,这就是为什么我在引用“override”一词时加上引号,以强调我对该术语的比喻使用。 - Andremoniy
3
为什么我们不应该在Java中使用protected static?在Java中,protected静态成员具有与public静态成员相同的可见性。这意味着子类可以访问其父类中受保护的静态成员,而不管它们是否在同一包中。因此,使用protected静态成员可能会破坏封装性和隐藏实现细节的原则。同时,在Java中,静态成员是类级别的成员,而非实例级别的成员。因此,受保护的静态成员可能无法正确地处理并发访问,因为所有实例都共享该静态成员。推荐的做法是使用公共静态方法来访问受保护的静态成员,以确保并发安全性,并在必要时进行同步处理。 - Murat Karagöz
3
这真的是一个重复的问题吗?那个问题涉及到受保护的静态变量,而这个问题涉及到受保护的静态方法。 - Necreaux
1
@bot 我认为编程语言中的任何构造都必须具有可理解的使用意义。对于 protected static 方法,我无法捕捉到这样的想法。 - Andremoniy
显示剩余9条评论
2个回答

3
但是,如果整个类不是final的话,这样“隐藏”静态方法有什么作用呢? 一个protected static方法可以让你为派生类提供“实用”类型的功能,而不必在公共API中公开它们,在那里它们可能本身并没有什么意义。 我不知道你所引用的getComparatorChain方法的具体实现,但我想它可能就是这样一个方法。如果它与任何特定实例无关,则会标记为static,并标记为protected,以便不成为公共API的一部分,但也允许派生类在自己的实现中重复使用该实用程序方法。

2
覆盖静态方法是指隐藏其实现。参见:Java文档的Overriding and Hiding Methods
静态方法:
如果子类定义了一个与超类中静态方法签名相同的静态方法,则子类中的方法会隐藏超类中的方法。
隐藏静态方法和重写实例方法之间的区别具有重要的含义: - 调用被重写的实例方法的版本是子类中的版本。 - 调用被隐藏的静态方法的版本取决于它是从超类还是从子类调用的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接