未知/通配符(?)方法调用中的通用类型

时间:2011-10-04 12:19:54

标签: java generics

我有以下两个接口:

public interface ParsedFile<K, V extends FileEntry>{...}

public interface MetricsProduces<K, V extends FileEntry>{
    Metrics generateMetrics(ParsedFile<K, V> parsedFile);
}

我有以下通用代码应该能够处理任何FileEntry类型:

Option<FileDefinition> option = fileContainer.matchFile(file);
if (option.isSome){
  FileDefinition fileDef = option.some();
  ParsedFileFactory<?> factory = filterDefinition.getFactory();
  ParsedFile<?, ?> parsedFile = factory.parseFile(file);
  MetricsProducer<?, ?> metricsProducer = fileDefinition.getMetricsProducer();
  Metrics metrics = metricsProducer.generateMetrics(parsedFile);
}

此代码块旨在能够在给定适当的FileDefinition的情况下解析任何类型的文件。但是我得到以下编译时错误:

The method generateMetrics(ParsedFile<capture#5-of ?, capture#6-of ? extends FileEntry>) 
in the type MetricsProducer<capture#5-of ?, cature#6-of ? extends FileEntry> 
is not applicable for the arguments 
(ParsedFile<capture#7 of ?, capture#8-of ? extends FileEntry>)

有没有办法让编译器知道“?” ParsedFile的类型与“?”相同MetricsProducer的类型?这样做还有其他选择吗?

修改

我已经修复了(如上所述这导致了一个强制转换警告)代码如下,但是想知道是否有更好的选择:

public interface MetricsProduces<K, V extends FileEntry>{
    Metrics generateMetrics(ParsedFile<?, ? extends FileEntry> parsedFile);
}

public class TasksMetricsProduces<String, TaskFileEntry> implements MetricsProduces<...>{

    public Metrics generateMetrics(ParsedFile<?, ? extends FileEntry> parsedFile){
         ParsedFile<String, TaskFileEntry> parsedFile2 = (ParsedFile<String, TaskFileEntry>)parsedFile;
    }
}

编辑2:每条评论/建议

所以我发现如果我早先锁定类型,我可以执行以下操作:

public interface FileDefinition<K, V extends FileEntry, T extends ParsedFile<K, V>>{...


public void myMethod(){
     for (FileDefinition<?, ?, ?> def : defs){
         process(def);
     }
}

private <K, V extends FileEntry, T extends ParsedFile<K, V>> process(FileDefinition<K, V, T> def){
     Factory<T> factory = def.getFactory();
     MetricsProducer<K, V> producer = def.getMetricsProducer();
     ParsedFile<K, V> parsedFile = factory.parseFile();
     Metrics metrics = producer.generateMetrics(parsedFile);
}

感谢您的建议。

4 个答案:

答案 0 :(得分:1)

关于您上面的评论和以下代码,我认为没有简单的解决方法:

ParsedFile<?, ?> parsedFile = factory.parseFile(file);
MetricsProducer<?, ?> metricsProducer = fileDefinition.getMetricsProducer();

只要factory.parseFile(...)ParsedFileFactory本身没有正确地进行paremeterized以及fileDefinition.getMetricsProducer()FileDefinition,您就永远无法确定两者所创建的对象这些方法是匹配的。

答案 1 :(得分:0)

也许你可以绑定?与此相似的类型参数:

<K, V extends FileEntry> void myMethod(){
    Option<FileDefinition> option = fileContainer.matchFile(file);
    if (option.isSome){
        FileDefinition fileDef = option.some();
        ParsedFileFactory<?> factory = filterDefinition.getFactory();
        ParsedFile<K, V> parsedFile = factory.parseFile(file);
        MetricsProducer<K, V> metricsProducer = fileDefinition.getMetricsProducer();
        Metrics metrics = metricsProducer.generateMetrics(parsedFile);
    }
}

答案 2 :(得分:0)

如果我之前锁定了泛型类型以向编译器显示对象的类型是相同的,那么它发现它是有效的。

public interface FileDefinition<K, V extends FileEntry, T extends ParsedFile<K, V>>{...


public void myMethod(){
     for (FileDefinition<?, ?, ?> def : defs){
         process(def);
     }
}

private <K, V extends FileEntry, T extends ParsedFile<K, V>> process(FileDefinition<K, V, T> def){
     Factory<T> factory = def.getFactory();
     MetricsProducer<K, V> producer = def.getMetricsProducer();
     ParsedFile<K, V> parsedFile = factory.parseFile();
     Metrics metrics = producer.generateMetrics(parsedFile);
}

答案 3 :(得分:-1)

MetricsProducer<?, ? extends FileEntry> metricsProducer = fileDefinition.getMetricsProducer();