java - 在所有方法调用上允许类型见证有什么意义?

标签 java generics

假设我们有如下两种方法:

public static <T> T genericReturn() { /*...*/ }
public static String stringReturn() { /*...*/ }

在调用任何方法时,无论是否有任何要求,您都可以提供类型见证:

String s;
s = Internet.<String>genericReturn(); //Type witness used in return type, returns String
s = Internet.<Integer>stringReturn(); //Type witness ignored, returns String

但是,我在 Java 中根本没有看到任何实际用途,除非无法推断类型(这通常表明存在更大的问题)。此外,如果使用不当,它就会被忽略,这一事实似乎违反直觉。那么在 Java 中使用这个有什么意义呢?

最佳答案

来自JLS §15.2.12.1 :

  • If the method invocation includes explicit type arguments, and the member is a generic method, then the number of type arguments is equal to the number of type parameters of the method.

This clause implies that a non-generic method may be potentially applicable to an invocation that supplies explicit type arguments. Indeed, it may turn out to be applicable. In such a case, the type arguments will simply be ignored.

后面是理由

This rule stems from issues of compatibility and principles of substitutability. Since interfaces or superclasses may be generified independently of their subtypes, we may override a generic method with a non-generic one. However, the overriding (non-generic) method must be applicable to calls to the generic method, including calls that explicitly pass type arguments. Otherwise the subtype would not be substitutable for its generified supertype.

沿着这个推理思路,让我们构建一个示例。假设在Java 1.4中,JDK有一个类

public class Foo
{
    /** check obj, and return it */
    public Object check(Object obj){ ... }
}

一些用户编写了一个扩展 Foo 的专有类并覆盖 check方法

public class MyFoo extends Foo
{
    public Object check(Object obj){ ... }
}

当 Java 1.5 引入泛型时,Foo.check概括为

    public <T> T check(T obj)

雄心勃勃的向后可比性目标要求 MyFoo仍然可以在 Java 1.5 中编译,无需修改;和MyFoo.check[Object->Object]仍然是 Foo.check[T->T] 的重写方法。

现在,根据上述理由,由于可以编译:

    MyFoo myFoo = new MyFoo();

    ((Foo)myFoo).<String>check("");

这也必须编译:

    myFoo.<String>check("");

尽管MyFoo.check不是通用的。

<小时/>

这听起来有些牵强。但即使我们接受这个论点,解决方案仍然过于宽泛和过度。 JLS 可以收紧它,以便 myFoo.<String,String>checkobj.<Blah>toString()是非法的,因为类型参数数量不匹配。他们可能没有时间解决这个问题,所以他们只是走了一条简单的路线。

关于java - 在所有方法调用上允许类型见证有什么意义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30811128/

相关文章:

java - 如何根据传递的类类型设计处理 Java 中 Collection 的方法?

java - 如何在构建器模式中使用泛型

swift - 如何在 Swift 中创建接受 Double 和 Int 的泛型类

class - typescript :无法导出作为通用接口(interface)并包含其他通用接口(interface)的模块

c# - 将泛型类型与 asp.net 用户控件一起使用

java - Java HashMap 的 Eclipse 警告

java - 将在 JBoss 4.2 上运行良好的应用程序部署到 JBoss 5 时出错

java - 通过目录选择器复制选定目录中的文件

java - Java 中的 TCP 服务器

java - 如何为二叉搜索树设计通用节点?