方法重载和泛型

Posted

技术标签:

【中文标题】方法重载和泛型【英文标题】:Method overloading and generics 【发布时间】:2013-06-16 00:42:53 【问题描述】:

在选择正确的重载方法时,Java 通常更喜欢普通方法而不是泛型方法,这可能会生成以下sscce:

public class GenericsTest 
    public static void main(String[] args) 
        myMethod(Integer.class, 10);
        myMethod(String.class, "overloaded method");
    

    public static <T> void myMethod(Class<T> klass, T foo) 
        System.out.println("hello world");
    

    public static <T> void myMethod(Class<T> klass, String bar) 
        System.out.println(bar);
    

输出:

hello world
overloaded method

有没有办法强制 Java 使用 Generic 版本?

【问题讨论】:

哇,四个完全不同但都很好的答案。 你有一个真实的场景可以分享,还是只是理论上的? 哈,我确实有一个真实的生活场景(在一个有比这更多方法的类中)但是后来(在我提出这个问题之后)我意识到我犯了一个错误并且方法确实有不同名字。但是这个问题还是很有趣的。 【参考方案1】:

不,不只是删除或隐藏更具体的重载。然而,如果它们的行为不同,它们应该只是具有不同的名称。如果它们的行为相同,则无论哪种方式都无关紧要。

【讨论】:

【参考方案2】:

我见过的一种方法是在不太常用的方法中添加一个虚拟参数:

public static <T> void myMethod(Class<T> klass, String bar, Void ignored) 
    System.out.println(bar);

这样称呼它

myMethod(String.class, "overloaded method", null);

否则

myMethod(String.class, "overloaded method");

调用泛型方法。

【讨论】:

【参考方案3】:

泛型方法允许使用类型参数来表达方法和/或其返回类型的一个或多个参数的类型之间的依赖关系。如果没有这样的依赖,就不应该使用泛型方法。

(来自here)

【讨论】:

【参考方案4】:

有没有办法强制 Java 使用 Generic 版本?

如果不删除、重命名或以其他方式更改第二种方法的签名,则并非如此。 (如果你想变得非常 hacky - 不要这样做 - 使用反射来调用该方法。)那是因为 Java's overload resolution procedure 会尝试 pick the most-specific method it can.

15.12.2.5。选择最具体的方法

如果多个成员方法既可访问又适用于方法调用,则有必要选择一个为运行时方法分派提供描述符。 Java 编程语言使用选择最具体的方法的规则。

非正式的直觉是,如果第一个方法处理的任何调用都可以传递给另一个方法而不会出现编译时类型错误,那么一个方法比另一个方法更具体。

【讨论】:

以上是关于方法重载和泛型的主要内容,如果未能解决你的问题,请参考以下文章

Java、静态方法绑定和泛型都包含一些方法重载

Java协变式覆盖(Override)和泛型重载(Overload)

c#泛型方法重载

C# 中的多态、重载和泛型

C#002 方法和接口

C#002 方法和接口