通用超类和超类类型的区别

20

我无法理解下面两个代码片段之间的区别。能否有人用简单的语言给我解释一下?

首先,我必须说我有很多类继承了一个名为BaseEntity的超类,那么以下代码片段的区别、优点和缺点是什么呢?

// 1
public <T extends BaseEntity> T getName(T t) {
    return t;
}

// 2
public BaseEntity getName(BaseEntity t) {
    return t;
}
4个回答

25
第一个代码片段更加灵活,因为它保留了“T”的实际类型。假设您有一个子类:
class SubEntity extends BaseEntity {}

在第一种情况下,您可以写成:
SubEntity result = getName(new SubEntity());

但在第二种情况下,您需要进行转换:

SubEntity result = (SubEntity)getName(new SubEntity());

7

使用这两种方法的主要区别在于第二种情况可能需要进行强制类型转换。

假设你有:

public class MyEntity extends BaseEntity {
}

通过第一种方法,您可以得到类似以下的内容:

MyEntity myEntity = ...
MyEntity entity = getName(myEntity);

用第二种方法,你需要写下以下代码: ```` code block ````
MyEntity entity = (MyEntity)getName(myEntity);

这是因为您在第一个方法中指定了具体类型。

4
我很惊讶之前的答案中没有人提到这一点,但两种方法声明之间有更根本的区别(这是第二种情况需要进行强制转换的原因)。对于您在此处提供的简单方法而言,这种区别并不重要,但对于执行与仅返回其参数不同的操作的方法来说,这可能会产生影响。
您的第一个方法声明要求返回类型与传入的参数为相同类型。所以:
public <T extends BaseEntity> T getName(T t) {
    return new SubEntity(); // Where SubEntity extends BaseEntity
}

无法编译,而

public BaseEntity getName(BaseEntity t) {
    return new SubEntity(); // Where SubEntity extends BaseEntity
}

即使传入方法的BaseEntity类型与SubEntity完全不同,这种做法也是完全合法的。


1

1) 在您的第一段代码中,您限制了返回方法应该是BaseEntity子类,并且输入参数必须是BaseEntity的相同子类

2) 在您的第二段代码中,方法的返回值和参数应该是BaseEntity子类


这不是真的。在第一个代码片段中,输入参数的类型必须是与“返回”值相同的BaseEntity子类。它不能只是任何类型的对象。在第二个片段中,“返回”值和输入参数也可以是BaseEntity的子类。 - Daniel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接