简体   繁体   English

在Java中重载方法

[英]Overloading of methods in Java

In the following code snippet, there are three versions of a method named show() . 在以下代码段中,有一个名为show()的方法的三个版本。

package overloading;

import java.util.ArrayList;
import java.util.List;

public final class Main
{
    private void show(Object object)
    {
        System.out.println("Object");
    }

    private void show(List<Object> list)  //Unused method
    {
        System.out.println("List");
    }

    private void show(Object[] objects)
    {
        System.out.println("Objects");
    }

    private void addToList()
    {
        List<String>list=new ArrayList<String>();
        list.add("String1");
        list.add("String2");
        list.add("String3");
        show(list); // Invokes the first version

        String []s={"111", "222", "333"};
        show(s);   // Invokes the last version
    }

    public static void main(String[] args)
    {
        new Main().addToList();
    }
}

In this simplest of Java code, this method call show(s); 在这个最简单的Java代码中,这个方法调用show(s); (the last line in the addToList() method) invokes the last version of the overloaded methods. addToList()方法中的最后一行)调用重载方法的最后一个版本 It supplies an array of strings - String[] and it is accepted by the receiving parameter of type Object[] . 它提供了一个字符串数组 - String[] ,它被Object[]类型的接收参数接受。

This function call show(list); 这个函数调用show(list); however attempts to invoke the first version of the overloaded methods. 但是尝试调用重载方法的第一个版本 It passes a list of type strings - List<String> which should be accepted by the middle version whose receiving parameter is of type List<Object> The middle version of the methods is completely unused. 它传递一个类型字符串List<String> - List<String> ,它应该被接收参数类型为List<Object>的中间版本接受。方法的中间版本是完全未使用的。 It is a compile-time error, if the first version is removed. 如果删除了第一个版本,则是编译时错误。

Why does this call show(list); 为什么这个电话show(list); not invoke this version - private void show(List<Object> list){} - the middle one? 调用此版本 - private void show(List<Object> list){} - 中间版本?

In short, List<Object> is NOT List<String> . 简而言之, List<Object>不是List<String>

To "fix" your code, use the following code 要“修复”您的代码,请使用以下代码

private void show(List<? extends Object> list)
{
    System.out.println("List");
}

Unlike arrays (which are covariant in Java), different instantiations of a generic type are not compatible to each other, not even explicitly. 与数组(在Java中是协变的)不同,泛型类型的不同实例化彼此不兼容,甚至不是显式的。

With the declaration Generic<Supertype> superGeneric; Generic<Subtype> subGeneric; 声明Generic<Supertype> superGeneric; Generic<Subtype> subGeneric; Generic<Supertype> superGeneric; Generic<Subtype> subGeneric; the compiler would report a conversion error for both castings (Generic<Subtype>)superGeneric and (Generic<Supertype>)subGeneric . 编译器将报告两个(Generic<Subtype>)superGeneric(Generic<Supertype>)subGeneric (Generic<Subtype>)superGeneric的转换错误。

This incompatibility may be softened by the wildcard if ? 如果通配符可以软化这种不兼容性? is used as actual type parameter: Generic<?> is the abstract supertype for all instantiations of the generic type. 用作实际类型参数: Generic<?>是泛型类型的所有实例化的抽象超类型。

Also see

List<Object> is not a superclass of List<String> in java. List<Object>不是java中List<String>的超类。 What you are assuming is that Java has covariance on generics, which it does NOT. 您所假设的是Java在泛型上具有协方差,但它没有。

What this means is that if A is a superclass of B , List<A> is NOT a superclass of List<B> 这意味着如果AB的超类, List<A>不是List<B>的超类

A similar problem is faced in Cannot convert generic to expanded nested type , You can see if any of the work arounds there works for you. 无法将泛型转换为扩展嵌套类型时遇到了类似的问题,您可以看看是否有适合您的工作。

Perhaps changing 或许改变

private void show(List<Object> list)

to

private void show(List<? extends Object> list)

Would work as you would expect? 会像你期望的那样工作吗?

I would say it is because the parameters are different, List <Object> Differs from List <String> Therefore when you call the overloaded method, it would default to the first one accepting just an Object. 我会说这是因为参数不同, List <Object>List <String> List <Object>不同因此当你调用重载方法时,默认为第一个只接受一个Object。

Here is a short example: 这是一个简短的例子:

public class Test
{
  public static void overload (Object o)
  {
    System.out.println ("Object");

  }

   public static void overload (List <Object> o)
  {
    System.out.println ("List Object");
  }

   public static void main (String [] args)
   {
     overload (new ArrayList <Object>()); //"List Object"
     overload (new ArrayList <String>()); //"Object"

   }
}

Parameterize the list with generics and everything should work. 使用泛型参数化列表,一切都应该有效。

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

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