简体   繁体   English

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

[英]Unknown / Wildcard (?) Generic type in method call

I have the following two interfaces: 我有以下两个界面:

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

And

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

I have the following generic code the should be able to handle any FileEntry types: 我有以下通用代码应能够处理任何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);
}

This block of code is designed to be able to parse any type of file given the appropriate FileDefinition. 在给定适当的FileDefinition的情况下,此代码块旨在能够解析任何类型的文件。 However I am getting the following compile-time error: 但是我收到以下编译时错误:

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>)

Is there a way to let the compiler know that the "?" 有没有办法让编译器知道“?” type of ParsedFile is the same as the "?" ParsedFile的类型与“?”相同 type of MetricsProducer? MetricsProducer的类型? Is there another option for doing this? 还有其他选择吗?

Edit: 编辑:

I have fixed (as noted this causes a cast warning) the code as follows but was wondering if there is a better option: 我已经修复了(如下所述会导致强制转换警告)以下代码,但想知道是否有更好的选择:

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;
    }
}

Edit 2: per comments / suggestions 编辑2:每个评论/建议

So I found that if I lock down the types earlier I can do the following: 因此,我发现如果我更早地锁定类型,则可以执行以下操作:

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);
}

Thanks for the suggestions. 感谢您的建议。

Regarding your comments above and the following code I think there is no easy soltion: 关于上面的注释和以下代码,我认为没有简单的解决方法:

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

as long as factory.parseFile(...) or ParsedFileFactory itself isn't paremeterized properly as well as fileDefinition.getMetricsProducer() or FileDefinition you can never be sure that the objects created by the two of these methods are matching. 只要不正确地参数化factory.parseFile(...)ParsedFileFactory本身以及fileDefinition.getMetricsProducer()FileDefinition ,就无法确定这两个方法创建的对象是否匹配。

Maybe you can bind the ? 也许您可以绑定? to the same type parameter in way similar to this: 更改为相同类型参数的方式类似于:

<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);
    }
}

Found that it worked if I locked down the generic types earlier to show the compiler that the types for the objects are the same. 发现如果我更早地锁定泛型类型以向编译器显示对象的类型相同,则它起作用。

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);
}
MetricsProducer<?, ? extends FileEntry> metricsProducer = fileDefinition.getMetricsProducer();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM