[google/guava]GraphBuilder.directed() 和 GraphBuilder.undirected() 不应在对象上参数化

2024-04-24 826 views
3

我觉得我一定错过了一些东西,但我根本不明白为什么这些方法看起来不像:

public static <N> GraphBuilder<N> directed() { ... }
public static <N> GraphBuilder<N> undirected() { ... }

当前的设计意味着除了使用这些模式之外,不可能获得GraphBuilder任何参数化,Object直到您调用nodeOrder,这将正确推断泛型类型并执行强制转换。 (顺便说一句,有这种通用的向下转型行为感觉很奇怪,nodeOrder但是,例如,allowsSelfLoops没有。)

回答

5

这有点不直观,但它与MultimapBuilderCacheBuilder所做的是同一件事,并且出于相同的原因。

build()请注意,当然,它还执行强制转换。

不采用类型化参数的方法(例如allowsSelfLoops())不执行任何转换,因为没有可供使用的类型信息。

5

如果您能详细说明或提供您在说“相同原因”时所指内容的链接,我将不胜感激。这可能会让我明白整个事情。

在我想到的情况下,有类型信息;它只是由上下文提供,就像调用build().

我理解为什么一旦您调用泛型类型绑定,技术上就不能再推迟了nodeOrder,但是(对我来说)这似乎表明绑定应该尽早发生。与nodeOrder其他操作相比,其他操作很特别,感觉很偶然。

GraphBuilder<String> builder1 = GraphBuilder.directed(); // illegal
GraphBuilder<String> builder2 = GraphBuilder.directed().allowSelfLoops(true); // illegal
GraphBuilder<String> builder3 = GraphBuilder.directed().allowSelfLoops(true).nodeOrder(ElementOrder.unordered()); // legal
7

nodeOrder 特殊,因为它自然地限制了构建器能够生成的图表类型。您提出了一种提前“人为”限制图形类型的方法,但调用nodeOrder仍然是“特殊的” 因为与其他方法不同,如果您传递冲突的类型,您可能会破坏编译。

等效的 CacheBuilder 问题(已解决的 WAI)是问题 738。

2

哦,我会说 CacheBuilder 有以下文档,而 GraphBuilder 可能应该有等效的文档:

@param <K> the most general key type this builder will be able to create caches for. This is
     normally {@code Object} unless it is constrained by using a method like {@code
     #removalListener}
3

哦,我现在明白了!我从未想象过构建器的类型会传达“我可以创建N其所有子类型的图表”,所以我不明白为什么您不希望这种行为。说得通。 :)

2

此外,至少对于较旧的编译器来说,当泛型位于链的末尾而不是开头时,Java 中的类型推断往往效果更好。

7

我现在已经对文档进行了更新以供审核,因此它应该会出现在 Guava 的下一个版本中。

感谢您鼓励我们改进我们的文档。 :)

3

您可能想到了这一点,但是ValueGraphBuilderNetworkBuilder可以使用这样的参数文档 ✌️

7

是的,这一变化也涵盖了它们,但感谢您的询问。 :)
它还提到,如果您使用静态方法创建类型, 则类型被指定(即,不要以 开头Object) 。*Builderfrom()