Java 访问参数化类型的参数化类型 简短问题
是否可以在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
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:
在这种情况下,我认为我们不能不铸造。下面是另一个没有boundedProducer
的版本,需要强制转换:
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,请看一看,我确实想将处理器的实现绑定到生产者的特定实现。我确实想我不想把它和任何特定种类联系起来