泛型超类和超类类型的区别

时间:2015-12-09 08:38:47

标签: java generics methods typesafe generic-method

我无法理解下面两个代码段之间的区别。有人可以帮我解释一下吗?

首先,我必须说我有很多扩展名为BaseEntity的超类的类,那么以下片段的区别,优点和缺点是什么?

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

// 2
public BaseEntity getName(BaseEntity t) {
    return t;
}

4 个答案:

答案 0 :(得分:24)

第一个代码段更灵活,因为它保留了T的实际类型。假设你有一个子类:

class SubEntity extends BaseEntity {}

在第一种情况下,你可以写:

SubEntity result = getName(new SubEntity());

但在第二种情况下,你需要一个演员:

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

答案 1 :(得分:7)

使用这两种方法时的主要区别在于可能需要在第二种情况下进行铸造。

我们说你有:

public class MyEntity extends BaseEntity {
}

使用第一种方法,您可以使用以下内容:

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

使用第二种方法时,你必须写:

MyEntity entity = (MyEntity)getName(myEntity);

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

答案 2 :(得分: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
}
即使传递给方法的BaseEntitySubEntity完全不同,

也完全合法。

答案 3 :(得分:1)

1)在你的第一个代码中,你有一个返回方法的限制应该是subclasses的{​​{1}},并且输入参数必须是BaseEntity的相同子类。

2)在你的第二个代码中你有方法的返回和参数应该是BaseEntity的{​​{1}}。