下面的通用魔术片段通过在Strings上缓存非常昂贵的函数(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的子类与这些功能一起使用时,则由程序员确定正确T
的T extends Phrase
行类型。
Function <>是不可变的,因此(X)
可以保证的运行时强制。但是,如果我想强制T
编译时进行类型检查:
<X> X memo(Function<Joke, X>);
)[类型擦除是否可以防止这种情况?]您能做的最好的事情是:
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界量化,例如Enum<E extends Enum<E>>
。
脖子有点痛,但通常可以。
注意,它不能保证P
是以下类型this
:
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) {}
但是总的来说,这使得更可能犯下更多类型的错误变得更加困难。
我是否必须在短语的所有子类中都使用委托函数?
由于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) {...}
}
(如果这是您通过“委托”所指的类型。否则,请随时进行澄清。)
您可以使用类型参数进行委派,例如:
class Phrase<P> {
abstract <X> X memo(Function<P, X> f);
}
class Joke extends Phrase<Joke> {
@Override
<X> X memo(Function<Joke, X> f) {...}
}
这避免了未经检查的转换。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句