Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么/何时应使用泛型方法?_Java_Oop_Generics - Fatal编程技术网

Java 为什么/何时应使用泛型方法?

Java 为什么/何时应使用泛型方法?,java,oop,generics,Java,Oop,Generics,在学习Java时,我遇到了泛型方法 public void foo(T变量){ 也就是说,一个方法接受一个类型未确定的参数(ála PHP?)。然而,我不知道这怎么会是一个好的解决方案——特别是因为我在经历了一个松散的语言之后爱上了一种强类型语言 有什么理由使用泛型方法吗?如果是这样的话,什么时候?泛型,以及其他一些东西,会给您提供一种提供模板的方法——也就是说,您想要做同样的事情,唯一的区别是类型 例如,查看,您将看到方法 添加(E) 对于您声明的同一类型的每个列表,add方法唯一不同的地方

在学习Java时,我遇到了泛型方法

public void foo(T变量){
也就是说,一个方法接受一个类型未确定的参数(ála PHP?)。然而,我不知道这怎么会是一个好的解决方案——特别是因为我在经历了一个松散的语言之后爱上了一种强类型语言


有什么理由使用泛型方法吗?如果是这样的话,什么时候?

泛型,以及其他一些东西,会给您提供一种提供模板的方法——也就是说,您想要做同样的事情,唯一的区别是类型

例如,查看,您将看到方法

添加(E)

对于您声明的同一类型的每个列表,
add
方法唯一不同的地方就是进入列表的对象的类型。这是泛型有用的一个主要例子。(在将泛型引入Java之前,您需要声明一个列表,并且可以向列表中添加任何内容,但在检索对象时必须强制转换该对象)

更具体地说,您可能需要两个ArrayList实例,一个采用type1,另一个采用type2。
add
的列表代码将执行相同的操作,为每个列表执行相同的代码(因为这两个列表都是
ArrayList
实例),对吗?所以唯一不同的是列表中的内容


(正如@michael指出的,
add
并不是泛型方法的真正例子,但是在链接的API中有真正的泛型方法,并且概念是相同的)

泛型函数一般没有非强类型。在编译时解析并检查类型。它不是一个未决定的类型,而是一系列可能的类型之一(这些类型可以被约束,在您的示例中它们不是)。在编译时,它是已知的和确定的


正如hvgotcodes所说,Collections API包含了许多这方面的好例子。

那些来自Java 5之前的背景的人都知道,在集合中存储对象,然后在使用它之前将其转换回正确的类型是多么不方便。泛型可以防止这些。它提供编译时类型安全性,并确保在集合中只插入正确的类型,并避免在运行时发生ClassCastException

因此,它提供了编译时类型安全性和强制转换。当您想要编写具有复杂方法签名的复杂API时,它将在编写API和使用API时为您节省大量的时间,并防止编写大量用于转换部件的代码,并在编译时捕获错误。只需查看
java.util.Collection
包并查看源代码

作为一名开发人员,我总是希望编译器在编译时捕获我的错误,并在需要编译时通知我,然后我将修复我的错误,并且在运行时不会有太多与类型安全相关的错误

有关更多信息,请参阅:


通用概念的主要目标是:

  • 为集合提供类型安全性,以便它们只能保存 一种特殊类型的对象
  • 解决排版问题
要仅保存字符串类型的对象,可以按如下方式声明ArrayList的通用版本:

ArrayList l=新的ArrayList()


要了解更多信息:

请查看java.util包,特别是泛型集合类,并与使用Object:)中的强制转换的旧方法进行比较。对于泛型方法,请特别查看
java.util.Collections
(该类带有“s”)。请注意:泛型方法仍然是强类型的,只是类型是由type参数决定的。例如,
public T foo(T variable){}
总是必须返回它接收到的相同类型的对象,而不是任何类型的对象。这是真的,但是列表api中有真正的泛型函数,总体思路是一样的。我们这些来自C#世界的人在泛型之前的世界中也有同样的痛苦:)编写类型安全集合是一件非常痛苦的事情。是的,绝对如此;)但是C#和java泛型之间有一个区别,java具有类型擦除功能,可以在编译后删除所有泛型并添加强制转换,因此我们在运行时无法访问泛型信息,例如通过反射,在这种情况下,
List
List
在运行时没有任何区别,但是C#在编译时不会删除这些信息,并且您可以在运行时访问泛型信息,
List
与C#中的
List
不同,如果您想编写一个同时支持泛型和非泛型的API用例您应该编写两次这些API;)
public <T> void foo(T variable) { }