繁体   English   中英

为什么 Java 库类中的转换器方法是非静态的?

[英]Why are converter methods in Java Library classes non-static?

我看到 Java 库类中的几个转换器方法是非静态的。 示例:Instant 的 toEpochMilli(),ArrayList 的 toArray()。 我们可以使用 static 方法,例如 toEpochMilli(Instant instant) 和 toArray(ArrayList arrayList) 来实现相同的目的,对吧? 这些方法是非静态的有什么具体原因吗?

评论中,您写道:

是的,它更像是一种实用方法,实用方法通常是 static

这似乎很好地反映了您的问题的心态。 它有两个问题。 一方面,“效用法”没有明确的定义,这使得这种分类非常主观。

其次,实用方法经常被(或曾经)实现为static方法这一事实并不表明这是一个应该复制的实际设计模式,只是因为它以前已经这样做过。

这是相当具有历史意义的妥协。 在 Java 8 之前,没有default方法,因此添加到接口的每个方法都必须实现,即使只是通过委托给另一个辅助方法。

作为一个实际的例子,如果在一开始就将sort添加到List接口中,则每个List实现者都必须处理它。 因此,它被作为static方法添加到Collections class中,这并不意味着有人认为

Collections.sort(list, comparator); // no import static by that time

好于

list.sort(comparator);

或者有一个一刀切的实施方案。 这不仅错过了像ArrayList这样的实现的优化机会,还意味着当列表恰好按正确的顺序时,错误地将其应用于不可变列表将不会被注意到。

现在我们有了default方法, List这样一个sort方法,所以实现者仍然不需要处理它,但他们可以在适当的时候覆盖该方法。 所以ArrayList有一个优化版本,不可变列表无条件抛出,实现返回Collections.synchronizedList可以使整个操作同步。

归类为“实用方法”在这里从未发挥过任何作用。 请注意,其他语言处理它的方式不同,例如通过扩展方法,它们各有优缺点,但也表明必须将实用方法的调用编写为static方法不是实际目标。 事实上,情况恰恰相反。

Static 不适用于 inheritance:

List<String> list1 = new ArrayList<>();
List<String> list2 = new LinkedList<>();

list1.size()
list2.size()
ArrayList.staticSize((ArrayList) list1)
LinkedList.staticSize((LinkedList) list2)
List.staticSize(list1); // NOT POSSIBLE

一个人会想要这样的东西:

interface List {
    static staticSize(List list) {
        return list.size();
    }
}

但是仍然使用了非静态size()

没有 static 调度,多态性。 (JVM 对其他语言有一些支持。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM