为了避免对Java通用方法进行运行时类型检查,必须重写吗?

西恩·塔特

下面的通用魔术片段通过在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的子类与这些功能一起使用时,则由程序员确定正确TT extends Phrase类型

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

  • 有什么方法可以将下层函数的类型约束转发到上层函数的类型约束?(在笑话的情况下有效地制作备忘录<X> X memo(Function<Joke, X>);)[类型擦除是否可以防止这种情况?]
  • 我是否必须在短语的所有子类中都使用委托函数?
  • 除了“只是不犯任何错误”以外,还有其他窍门吗?
Radiodef

您能做的最好的事情是:

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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何避免在此代码中进行运行时类型检查?

来自分类Dev

使用Haskell / cabal / stack进行运行时类型检查

来自分类Dev

java通用方法,运行时错误,

来自分类Dev

我可以在运行时检查内置类型吗?

来自分类Dev

运行时通用类型确定

来自分类Dev

调用通用方法并在运行时设置通用类型

来自分类Dev

@type指令在Elixir中的defstruct中的用法。没有针对该字段执行运行时类型检查

来自分类Dev

可以静态分析Julia(julia-lang)代码以避免运行时类型错误吗?

来自分类Dev

并行运行时,Java-8的DoubleStream.sum()方法是否稳定?

来自分类Dev

您可以在运行时检查对象是否符合Flow类型吗?

来自分类Dev

C#Lambda表达式类型安全吗?何时检查(编译时间/运行时)?

来自分类Dev

Android:检查是否必须询问运行时权限

来自分类Dev

Android:检查是否必须询问运行时权限

来自分类Dev

从对象列表创建运行时已知类型的列表并调用通用方法

来自分类Dev

接受“通用”枚举作为参数,然后在运行时转换为 diff 枚举类型的方法

来自分类Dev

在Java中,为什么在运行时没有通用类型信息?

来自分类Dev

ModelMapper在运行时更改通用类型-奇怪的行为

来自分类Dev

在运行时将对象转换为通用类型

来自分类Dev

使用运行时给定的类型创建通用映射

来自分类Dev

在运行时将对象转换为通用类型

来自分类Dev

我可以在运行时在DevExpress的PivotGrid中对DateTime类型的数据进行分组吗?

来自分类Dev

是否可以执行运行时类型检查以确定某个属性是否是具有特定调用签名和返回类型的函数?

来自分类Dev

如何在运行时重写FormControl方法?

来自分类Dev

使用C ++通用编程对x和y类型的所有排列进行func(x,y)的运行时调用

来自分类Dev

Java:我可以在运行时将运行时异常注入到任意类方法中吗?

来自分类Dev

如何在运行时同时检查'instanceof'和Java对象的泛型类型?

来自分类Dev

您可以在运行时检查Java 8 lambda的字节码吗?

来自分类Dev

在运行时检查属性或方法是否存在?检查运行时是否存在 Trait?

来自分类Dev

如何在运行时检查类型?

Related 相关文章

  1. 1

    如何避免在此代码中进行运行时类型检查?

  2. 2

    使用Haskell / cabal / stack进行运行时类型检查

  3. 3

    java通用方法,运行时错误,

  4. 4

    我可以在运行时检查内置类型吗?

  5. 5

    运行时通用类型确定

  6. 6

    调用通用方法并在运行时设置通用类型

  7. 7

    @type指令在Elixir中的defstruct中的用法。没有针对该字段执行运行时类型检查

  8. 8

    可以静态分析Julia(julia-lang)代码以避免运行时类型错误吗?

  9. 9

    并行运行时,Java-8的DoubleStream.sum()方法是否稳定?

  10. 10

    您可以在运行时检查对象是否符合Flow类型吗?

  11. 11

    C#Lambda表达式类型安全吗?何时检查(编译时间/运行时)?

  12. 12

    Android:检查是否必须询问运行时权限

  13. 13

    Android:检查是否必须询问运行时权限

  14. 14

    从对象列表创建运行时已知类型的列表并调用通用方法

  15. 15

    接受“通用”枚举作为参数,然后在运行时转换为 diff 枚举类型的方法

  16. 16

    在Java中,为什么在运行时没有通用类型信息?

  17. 17

    ModelMapper在运行时更改通用类型-奇怪的行为

  18. 18

    在运行时将对象转换为通用类型

  19. 19

    使用运行时给定的类型创建通用映射

  20. 20

    在运行时将对象转换为通用类型

  21. 21

    我可以在运行时在DevExpress的PivotGrid中对DateTime类型的数据进行分组吗?

  22. 22

    是否可以执行运行时类型检查以确定某个属性是否是具有特定调用签名和返回类型的函数?

  23. 23

    如何在运行时重写FormControl方法?

  24. 24

    使用C ++通用编程对x和y类型的所有排列进行func(x,y)的运行时调用

  25. 25

    Java:我可以在运行时将运行时异常注入到任意类方法中吗?

  26. 26

    如何在运行时同时检查'instanceof'和Java对象的泛型类型?

  27. 27

    您可以在运行时检查Java 8 lambda的字节码吗?

  28. 28

    在运行时检查属性或方法是否存在?检查运行时是否存在 Trait?

  29. 29

    如何在运行时检查类型?

热门标签

归档