Java 访问参数化类型的参数化类型 简短问题

Java 访问参数化类型的参数化类型 简短问题,java,generics,Java,Generics,是否可以在Java中执行类似的操作: public interface Processor<T extends Producer> { <T2> T2 process(T<T2> producer); } 公共接口处理器{ T2工艺(T生产商); } 其中生产者声明为生产者 长问题 如果Java中的类型A是用同样是泛型的类型B参数化的,那么在Java中是否可能以某种方式使用参数化的类型B?我知道,这是个谜 假设我们有一个通用的生产者界面: publ

是否可以在Java中执行类似的操作:

public interface Processor<T extends Producer> {
    <T2> T2 process(T<T2> producer);
}
公共接口处理器{
T2工艺(T生产商);
}
其中生产者声明为
生产者

长问题 如果Java中的类型A是用同样是泛型的类型B参数化的,那么在Java中是否可能以某种方式使用参数化的类型B?我知道,这是个谜

假设我们有一个通用的生产者界面:

public interface Producer<T> {
    T produce();
}
public interface Processor<T extends Producer, T2> {
    T2 process(T producer);
}
公共接口生成器{
T生产();
}
这个接口的实现也是通用的。它们在生成对象的类型上没有区别,而是在生成方式上有所不同,因此可能有:DatabaseProducer、RandomProducer等

我们还有一个处理器接口。处理器的特定实现能够与生产者的特定实现协同工作,但处理器也不关心被处理对象的类型。我们可以很容易地实施这种情况:

public class MyProducer<T> implements Producer<T> {
    @Override
    public T produce() {
        (...)
    }
}

public class MyProcessor implements Processor<MyProducer> {
    <T> T process(MyProducer<T> producer) {
        return producer.produce();
    }
}
公共类MyProducer实现Producer{
@凌驾
公共产品{
(...)
}
}
公共类MyProcessor实现处理器{
T过程(MyProducer){
返回producer.product();
}
}
MyProcessor的process()方法获取泛型MyProducer并只返回它生成的内容。此实现将与字符串、整数或其他对象的生产者一起工作,只要生产者是MyProducer类型

现在的问题是如何编写通用处理器接口。此接口由Producer类型参数化,该方法应返回相关Producer的参数化类型

我们不能这样做:

public interface Processor<T extends Producer> {
    <T2> T2 process(T<T2> producer);
}
public interface Processor<T extends Producer> {
    T.T process(T producer);
}
公共接口处理器{
T2工艺(T生产商);
}
或者类似的:

public interface Processor<T extends Producer> {
    <T2> T2 process(T<T2> producer);
}
public interface Processor<T extends Producer> {
    T.T process(T producer);
}
公共接口处理器{
T.T工艺(T生产商);
}
甚至可以用Java实现吗?是否有任何理由不能或不应该支持它,或者这只是缺少的功能?我认为编译器可以完全理解这个场景,并检查类型是否正确


更新

具有两种参数化类型的解决方案,例如:

public interface Processor<T extends Producer<T2>, T2> {
    T2 process(T producer);
}
公共接口处理器{
T2工艺(T生产商);
}
这不是我要找的。请注意,MyProcessor未绑定到任何特定类型的生成对象。在调用站点推断了从process()方法返回的类型

我也了解类型擦除的工作原理和相关问题。问题是:由于类型擦除,这种情况是有问题的还是不可能的?我相信没有

如果我们有常规通用方法,例如:

<T> T process(MyProducer<T> producer) {
    return producer.produce();
}
T过程(MyProducer){
返回producer.product();
}
我们称之为:

MyProducer<String> prod = (...);
String result = processor.process(prod);
myproducerprod=(…);
字符串结果=处理器进程(prod);
那么一切都会好起来的。当然,在这种情况下字符串会被擦除,process()和product()方法都会返回结果字节码中的对象,但编译器知道MyProducer.product()实际上会返回字符串,所以process()也会返回字符串。我不明白为什么在我的情况下它不能以同样的方式工作:

public interface Processor<T extends Producer> {
    <T2> T2 process(T<T2> producer);
}
公共接口处理器{
T2工艺(T生产商);
}

编译器从传递的producer对象推断调用站点上返回的类型,并且可以用与上面相同的方式证明实现是正确的。我认为Java现在唯一缺少的是编译器应该注意到T扩展了泛型类型,因此
T
可以像
Producer
一样处理。也许我在这里看不到什么重要的东西。

您可以在类级别或方法级别使用泛型。如果您需要让处理器使用特定类型的生产者,则可以将处理器定义为:

public interface Producer<T> {
    T produce();
}

public interface Processor< T, P extends Producer<T> > {
    public T process(P producer);
}

public class MyProducer<T> implements Producer<T> {
    @Override
    public T produce() {
        return null;
    }
}

public class MyProcessor<T> implements Processor<T, MyProducer<T> > {

    public T process(MyProducer<T> producer) {
        return producer.produce();
    }
}
顺便说一句,我不喜欢您将MyProducer声明为泛型,而不显示如何知道在
producer()
方法中返回什么类型的对象

更新2:

在这种情况下,我认为我们不能不铸造。下面是另一个没有bounded
Producer
的版本,需要强制转换:

public static interface Processor< P extends Producer<?> > {
    public <T> T process(P producer);
}

public static class MyProcessor implements Processor< MyProducer<?> > {

    @SuppressWarnings("unchecked")
    public <T> T process(MyProducer<?> producer) {
        return (T)producer.produce();
    }
}

//again this will work without any compilation errors
String result = new MyProcessor().process( new MyProducer<String>() 
公共静态接口处理器{
公共T过程(P生产者);
}
公共静态类MyProcessor实现处理器{
@抑制警告(“未选中”)
公共T流程(MyProducer){
return(T)producer.product();
}
}
//同样,这将在没有任何编译错误的情况下工作
字符串结果=新的MyProcessor().process(新的MyProducer())

这是不可能的,因为您的泛型类型是

不可偿还类型

可修改类型是类型信息完全可用的类型 在运行时。这包括原语、非泛型类型、原始类型、, 以及未绑定通配符的调用

不可恢复类型是指信息已被删除的类型 编译时逐类型擦除-调用 未定义为无界通配符。不可重新定义的类型没有 其所有信息在运行时可用。不可恢复的示例 类型是List和List;JVM无法告诉 运行时这些类型之间的差异。如上的限制所示 泛型,在某些情况下,不可恢复类型 不能使用:例如,在instanceof表达式中,或作为 数组中的元素

通过在界面中使用其他类型,可以实现非常简单的解决方法:

public interface Producer<T> {
    T produce();
}
public interface Processor<T extends Producer, T2> {
    T2 process(T producer);
}

但是,我没有想到这会有什么用处。

您应该做的第一件事是在Java编译器中启用所有警告,并解决这些警告。特别是,请注意有关原始类型的警告。@broot,请看一看,我确实想将处理器的实现绑定到生产者的特定实现。我确实想我不想把它和任何特定种类联系起来