Java编译器无法推断泛型链上的类型

Java编译器无法推断泛型链上的类型,java,generics,type-inference,generic-programming,Java,Generics,Type Inference,Generic Programming,如下文所述(我可能会解释得很糟糕,但请注意这一点): 我想了解这个问题背后的原理,以便将这些知识应用到实际问题中。 问题开始 我在一个系统中工作,该系统旨在成为一个抽象库,供许多子系统使用。我们的想法是通过实现来扩展标准行为。 我的问题是java编译器无法推断方法参数类型,尽管这毫无意义,因为在每个相关的泛型类/方法上都设置了很好的边界 下面是一个例子,再现问题的最小例子。我知道这个例子看起来有点傻,但这是因为简化了: public class Test { public st

如下文所述(我可能会解释得很糟糕,但请注意这一点):

我想了解这个问题背后的原理,以便将这些知识应用到实际问题中。


问题开始

我在一个系统中工作,该系统旨在成为一个抽象库,供许多子系统使用。我们的想法是通过实现来扩展标准行为。 我的问题是java编译器无法推断方法参数类型,尽管这毫无意义,因为在每个相关的泛型类/方法上都设置了很好的边界

下面是一个例子,再现问题的最小例子。我知道这个例子看起来有点傻,但这是因为简化了:

    public class Test {
    public static void main(String[] args) {
        Gen<? extends Base> gen = new HijaGen();
        gen.applyTo(Hija.EXAMPLE);
    }
    private interface Base {
        String getName();
    }
    private enum Hija implements Base {
        EXAMPLE;
        @Override
        public String getName() {
            return this.name();
        }
    }
    private interface Gen<T extends Base> {
        boolean applyTo(T base);
    }
    private static class HijaGen implements Gen<Hija> {
        @Override
        public boolean applyTo(Hija base) {
            return false;
        }
    }
}
公共类测试{
公共静态void main(字符串[]args){

GenA
Gen我认为文档中解释了一个类似的问题,他们提出的问题是制作一个助手(或包装器)来澄清类型。因此我想您可以尝试添加此函数:

private static <T extends Base> boolean applyTo(Gen<T> gen, T base){
    return gen.applyTo(base);
}

根据Carlos提到的内容,还有一种方法可以解决这个问题。如果您确信
Gen
的实施供应商,可以使用该方法

在这里,我们定义了一个工厂方法来创建
Gen
实现的实例,并将其强制转换到
Gen
,而不是调用
applyTo()
的助手,我认为这对于所有实际用途都是安全的
不需要是静态的。示例中的其余代码保持不变

public static void main( String[] args ){
    Gen<Base> gen = (Gen<Base>) get();
    gen.applyTo( Hija.EXAMPLE );
}

static Gen<? extends Base> get(){
    /* Create the instance of the Gen interface implementation here. */
    return new HijaGen();
}
publicstaticvoidmain(字符串[]args){
Gen=(Gen)get();
阿普利托将军(Hija.EXAMPLE);
}

静态GenOr<代码>Gen@TomHawtin-tackline或just
HijaGen
我认为OP追求的是一个一般原则,而不仅仅是获取一些随机代码进行编译。@TomHawtin tackline参见第一段多谢大家,我将尝试进一步澄清:此代码用于库,因此解决方案无法指定类型从那时起,它就无法通过特定的实现进行扩展。我已经意识到,如果我指定泛型类型而不是抛出类型通配符,它将完美地工作。但我的问题是,即使Hija将Base子类化,并且方法公司需要Base子类,它也永远不会编译……我想知道理解这个问题背后的原理,以便我能将这些知识应用到实际问题中没有真正的帮助。了解如何访问库是很重要的。您提供的
main
方法是一个示例调用,但不是一个您希望需要库的方法。当使用库时,客户会考虑哪些变量类型是相关的问题。@daniu我想您关注的是一些不需要的问题重要的是,具体的问题是:如果Hija满足(至少在理论上)条件,该方法怎么可能不接受Hija公司要求的方法是什么?提及图书馆只是为了澄清为什么我不能使用Gen这一快速解决方案。您标记为已接受的答案正好包含了我的意见,即对图书馆的调用可能需要更改。
public static void main(String[] args) {
    boolean b = applyTo(new HijaGen(), Hija.EXAMPLE);
}
public static void main( String[] args ){
    Gen<Base> gen = (Gen<Base>) get();
    gen.applyTo( Hija.EXAMPLE );
}

static Gen<? extends Base> get(){
    /* Create the instance of the Gen interface implementation here. */
    return new HijaGen();
}