【问题标题】:Differences between generic methods in javajava中泛型方法的区别
【发布时间】:2016-02-01 16:16:44
【问题描述】:

假设我有这个界面:

public interface Lookup<T> {
     public T find(String name);
}

以下方法有区别吗?

1)

public void process(String name, Lookup<?> table) {
    System.out.println(table.find(name));
}

2)

public <S,T extends Lookup<S>> void process(String name, T table) {
    System.out.println(table.find(name));
}

在第一种方法中,我使用的是 '?'所以我可以在 Lookup 中使用任何类型,在第二个中我使用 T 和 S 所以 S 所以我也可以在 T 中使用任何类型,女巫是 Lookup。

【问题讨论】:

  • 类型擦除后,它们看起来都像第一个。

标签: java oop generics methods generic-programming


【解决方案1】:

process() 方法中没有发现差异,它在调用程序中找到。当您指定Lookup&lt;?&gt; 时,您放弃了任何编译时类型检查的机会,而如果您使用第二种方法,您的table 必须匹配T extends Lookup&lt;S&gt;。你至少对编译器发现问题有一些希望。

【讨论】:

  • 由于对S 没有限制,所以没有错误,编译器可以在这里捕获。任何Lookup 都可以接受,因此与Lookup&lt;?&gt; 没有区别……
  • @Holger 差不多。如果我用&lt;Foo, FooLookup&gt;process("Baz", myBarLookup) 调用它(其中FooLookup extends Lookup&lt;Foo&gt;myBarLookupBarLookup extends Lookup&lt;Bar&gt; 的一个实例,那么编译器可以捕获它。因此,“至少...一些希望”行。
  • 当然,但是为什么任何人都应该提供这些显式的&lt;Foo, FooLookup&gt; 类型参数只是为了让编译器拒绝调用,而将不带类型参数的myBarLookup 传递给方法不仅被接受,而且实际上会工作没有问题,因为方法本身既不依赖于Foo也不依赖Bar?这里的重点不是我们不能捕获所有的错误,而是没有没有要捕获的错误。这些方法适用于Lookup 的所有子类型,并且让编译器拒绝该方法实际可以处理的东西的机会是没有胜利的。
  • @Holger 方法是做作的(琐碎的println),使用的例子是做作的,使用场景是虚构的。关键是有的区别。它是否有用是另一个问题。而且我几乎完全同意您的观点,即第二个声明的潜在效用非常渺茫。
  • 只要实现足够简单,可以实际使用Lookup&lt;?&gt;(或者通常是通配符类型),就没有理由为其引入命名类型变量。调用者不能对实际类型做任何错误。但是,如果实现不适用于通配符类型,则使用哪个声明毫无疑问......
【解决方案2】:
  1. table.find会返回T,如果不是String则需要转成String:

    System.out.println(table.find(name).toString());

  2. 对我来说没什么意义,

【讨论】:

    猜你喜欢
    • 2020-11-02
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多