有没有办法解决Java无法将泛型参数转发给非泛型类型的问题?

时间:2018-01-20 21:10:03

标签: generics kotlin

在C ++中,我可以编写如下代码:

class Shader {
    ...
    void setUniform(GLuint handle, int value);
    void setUniform(GLuint handle, float value);
    void setUniform(GLuint handle, const std::vector<float> &value);
    ...
};

class UniformValueBase {
    ...
    GLuint handle;
    Shader &shader;
    virtual void apply() = 0;
};

template<typename T> class UniformValue: public UniformValueBase {
    ...
    T value;
    virtual void apply() override {
        shader.setUniform(handle, value);
};

并且当TsetUniform中具有Shader方法的任何类型时,它将起作用,如果我尝试使用不受支持的T,则无法编译正是我想要的行为。

不幸的是,等效在Java或Kotlin中不起作用,因为泛型基于类型擦除,意味着UniformValueT Object实现Any / UniformValueBase

我只需要支持大约六种不同的类型,因此使用{{1}}的非通用子类而不是泛型是可行的,但是有一个优雅且可扩展的习惯用法,要么使用Kotlin具有的功能Java没有,或者两种语言都有效?

2 个答案:

答案 0 :(得分:2)

基本原因并不是真正的类型擦除:它是因为C ++模板在实例化后进行了类型检查,而Java(以及Kotlin和其他大多数具有此功能的语言)都会检查通用代码本身。因此,您需要约束,要求T拥有静态方法,Kotlin和Java都不支持这些。我所知道的唯一语言是F#,它在JVM上是不可用的。 Scala有一个非常好的通用解决方案,称为类型类模式,但在Kotlin中尚未得到支持。

答案 1 :(得分:-1)

看起来这是不可能的。类型正在Java中删除,并且没有模板。