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

发布于 2024-12-08 04:47:10 字数 2455 浏览 0 评论 0原文

我有以下两个接口:

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

感谢您的建议。

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:

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. 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 "?" type of 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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

对你的占有欲 2024-12-15 04:47:10

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

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

只要 factory.parseFile(...)ParsedFileFactory 本身没有正确参数化为以及 fileDefinition.getMetricsProducer()FileDefinition 您永远无法确定这两个方法创建的对象是否匹配。

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.

浪漫人生路 2024-12-15 04:47:10

也许你可以绑定?以类似于此的方式传递给相同类型的参数:

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

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);
    }
}
×眷恋的温暖 2024-12-15 04:47:10

发现如果我提前锁定泛型类型以向编译器显示对象的类型是相同的,它就会起作用。

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

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);
}
慢慢从新开始 2024-12-15 04:47:10
MetricsProducer<?, ? extends FileEntry> metricsProducer = fileDefinition.getMetricsProducer();
MetricsProducer<?, ? extends FileEntry> metricsProducer = fileDefinition.getMetricsProducer();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文