gpt4 book ai didi

java - 是否需要重写以避免对 Java 泛型方法进行运行时类型检查?

转载 作者:行者123 更新时间:2023-11-29 05:06:13 25 4
gpt4 key购买 nike

下面的通用魔术片段通过在字符串(Phrase 简单地包装)上缓存非常昂贵的函数,让我省去了一些麻烦。

public class Phrase {
private final ConcurrentHashMap<Function<? extends Phrase, ?>, Object> memos;
public final String text;
public <X, T extends Phrase> X memo(Function<T, X> app) {
return (X) memos.computeIfAbsent(app, unused -> app.apply((T) this));
}
}
// Example follows
public class Joke extends Phrase {
boolean isoffcolor;
}
public class BigramJokeEvaluator {
public Boolean static isFunny(Joke joke) {
return !joke.isoffcolor;
}
}
public class MilesAway {
public static void main(String[] args) {
// Boom
new Phrase("Moo goes the cow!").memo(BigramJokeEvaluator::isFunny);
}
}

我有几个 Phrase 的子类,它们有各自的功能,当其他模块使用 Phrase 的子类和这些功能时,程序员需要确保类型 TT extends Phrase正确排列。

Function<> 是不可变的,因此 (X) 的运行时强制有保证。但是如果我想对 T 进行强制转换进入编译时类型检查:

  • 有什么方法可以将低层函数的类型约束转发到高层函数的类型约束吗? (在 Joke 的情况下有效地制作备忘录,就好像它是 <X> X memo(Function<Joke, X>); )[类型删除是否可以防止这种情况?]
  • 是否必须在 Phrase 的所有子类中创建委托(delegate)函数?
  • 除了“不犯任何错误”之外,还有其他技巧吗?

最佳答案

你能做的最好的是:

public class Phrase<P extends Phrase<P>> {
private final ConcurrentHashMap<Function<P, ?>, Object> memos;
public final String text;
public <X> X memo(Function<P, X> app) {
return (X) memos.computeIfAbsent(app, unused -> app.apply((P) this));
}
}

class Joke extends Phrase<Joke> {...}

这叫做 F-bounded quantification它被例如使用 Enum<E extends Enum<E>> .

脖子有点痛,但总的来说是有效的。

请注意,它不保证 Pthis 的类型:

class Joke extends Phrase<Joke> {}
// oops
class Troll extends Phrase<Joke> {}

也不可能捕获 Class<? extends Phrase<?>> :

{
Class<? extends Phrase<?>> j = Joke.class;
m( j ); // fails, but would pass if P was not F-bounded
}
static <P extends Phrase<P>> void m(Class<P> c) {}

但总的来说,它更难犯更可能类型的错误。

Do I have to make delegate functions in all the subclasses of Phrase?

委托(delegate)给子类很困难,因为 1. 没有协变参数和 2. 删除。

class Phrase {
...
<X> X memo(Function<Phrase, X> f) {...}
}

class Joke extends Phrase {
...
// this is a compiler error
// (technically, I think it's classified as
// "override-equivalent", but specified to fail)
<X> X memo(Function<Joke, X> f) {...}
}

(如果这是您所说的“委托(delegate)”所指的类型。否则,请随时澄清。)

可以使用类型参数进行委托(delegate),例如:

class Phrase<P> {
abstract <X> X memo(Function<P, X> f);
}
class Joke extends Phrase<Joke> {
@Override
<X> X memo(Function<Joke, X> f) {...}
}

这避免了未经检查的转换。

关于java - 是否需要重写以避免对 Java 泛型方法进行运行时类型检查?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30294021/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com