Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/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 什么是通用方法,如何<;T>;在这种情况下有约束力吗?_Java_Generics - Fatal编程技术网

Java 什么是通用方法,如何<;T>;在这种情况下有约束力吗?

Java 什么是通用方法,如何<;T>;在这种情况下有约束力吗?,java,generics,Java,Generics,前言:我了解泛型以及它们是如何在类级别声明的(例如类MyClass),但我从未见过它在静态方法级别声明,并且没有任何显式绑定(例如类MySubclass扩展MyClass) 我在正在开发的一个应用程序中发现了这个代码片段(这部分不是我写的)。我从未见过这样声明的方法未在类中的任何其他位置定义Intent.getExtras().get()返回一个对象,该对象实际上可能是字符串,布尔值…等等 private static <T> T getItemExtra(final Intent

前言:我了解泛型以及它们是如何在类级别声明的(例如
类MyClass
),但我从未见过它在静态方法级别声明,并且没有任何显式绑定(例如
类MySubclass扩展MyClass

我在正在开发的一个应用程序中发现了这个代码片段(这部分不是我写的)。我从未见过这样声明的方法<代码>未在类中的任何其他位置定义
Intent.getExtras().get()
返回一个
对象
,该对象实际上可能是
字符串
布尔值
…等等

private static <T> T getItemExtra(final Intent intent, final String extraName) {
    T item = null;

    if(intent != null && intent.getExtras() != null) {
        item = (T) intent.getExtras().get(extraName);
    }

    return item;
}

JVM如何知道用于
的类型?(是的,此方法编译并执行成功)。

T
是一种类型接口。在本例中,返回类型是一个类型接口,因此只要说
getItemExtra(…)
将返回一个
String
Uri
就足以让编译器知道此方法将返回该对象。尽管如此,这并不是最好的类型接口示例,所以这里有一个更简单的示例

ArrayList
是使用类型接口实现的,除非您告诉ArrayList它将包含什么对象类型,除非他们使用的不是
T
,而是
E
,这很好,因为只要您在整个实现过程中使用相同的字符,字符就是任意的

以下是一段来自实际案例的相关片段:

公共类ArrayList扩展了AbstractList
实现列表、随机访问、可克隆、java.io.Serializable
{

因此,如果您声明
ArrayList
,编译器将在编译时用
String
替换
E
ArrayList
也是如此,它将在整个实现过程中用
YourCustomObject
替换
E

这在Java中被称为a。T-in表示一种类型,您可以使用通常指定。然后,编译器将用您替换的类型替换T的任何实例。如果不指定,编译器将尝试从可用信息推断正确的类型

您应该阅读Java教程以获得更深入的解释

JVM如何知道用于
的类型

基本答案是,它不是。在Java中,泛型类型由类型检查器在编译时使用,但在程序实际运行时从程序中删除。例如,在
项=(t)intent.getExtras().get(extraName)中转换为
t
在运行时实际上不做任何事情:它实际上是对
对象的强制转换,无论调用方希望
t
是什么类型。(这与对正常类型的强制转换不同,如
String
,如果您尝试强制转换错误的内容,程序将立即失败并出现异常。)

不需要检查就可以强制转换到
T
,这是Java类型系统中的一个漏洞,可能会导致奇怪的类强制转换异常

String s = getItemExtra(...); 
s.toLowerCase();

但是
getItemExtra
不返回字符串,那么第二行会出现异常,告诉您
s
不是字符串,即使该行上没有强制转换。因此,当Java编译器看到对
t
的强制转换时,它会生成一个未经检查的强制转换警告,告诉您它无法检查您的typecast是合法的,您可能会遇到这样的问题。

事实上,您在第一行得到一个异常,因为第一行变成了
String s=(String)getItemExtra(…)
。这不是另一个问题的重复。@Nilish我问的是泛型方法,不是泛型类。我已经更新了这个问题以反映这一点。@OliverGondža是的,我必须承认这是重复的。我的问题是关于泛型方法,不是泛型类。这是同一件事,一件事,你在构造函数中指定,另一件你在调用该方法。
public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
String s = getItemExtra(...); 
s.toLowerCase();