[英]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<?>
是泛型类型的所有实例化的抽象超类型。
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>
这意味着如果A
是B
的超类, 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.