当我阅读 Effective Java 第27项时,UnaryFunction<Object>
和UnaryFunction<T>
之间的类型转换让我感到困惑。
interface UnaryFunction<T> {
T apply(T t);
}
public class Main {
private static final UnaryFunction<Object> IDENTITY = new UnaryFunction<Object>() {
public Object apply(Object t) {
return t;
}
};
@SuppressWarnings("unchecked")
public static <T> UnaryFunction<T> identityFunction() {
return (UnaryFunction<T>) IDENTITY;
}
public static void main(String ... args) {
UnaryFunction<A> identityA = Main.identityFunction();
A a = identityA.apply(new A());
}
}
class A {}
为什么UnaryFunction<Object>
可以投放到UnaryFunction<T>
?
我知道通用类型将在编译后删除。因此(UnaryFunction<T>) IDENTITY
最终会(UnaryFunction<Object>) IDENTITY
,这将在运行时工作。
但编译器不允许直接将UnaryFunction<Object>
转换为UnaryFunction<A>
。
UnaryFunction<A> identityA = (UnaryFunction<A>)IDENTITY;
//incompatible types: UnaryFunction<java.lang.Object> cannot be converted to UnaryFunction<A>
UnaryFunction<Object>
和UnaryFunction<T>
之间没有继承关系。那么为什么UnaryFunction<Object>
可以投放到UnaryFunction<T>
?
答案 0 :(得分:4)
由于类型擦除,没有绑定(... extends ...
)的所有泛型类型都被视为Object
。因此,此强制转换可能对T
的某些值有效。@SuppressWarnings("unchecked")
告诉编译器你正在做正确的事情,所以警告被抑制。
投射到特定类型是有问题的。我们假设您正在处理List<Object>
,其中List<A>
A
是A
类。在这种情况下,列表可能包含UnaryFunction<Object>
的超类型的元素,因此这个强制转换是不合理的,因此编译器不允许它。在函数(IDENTITY = t -> new Object();
)的情况下,暗示它可以返回一个Object。假设您的代码为UnaryFunction<A>
,在这种情况下,转换为Object
会导致UnaryFunction<T>
不正确。在T
为T
的情况下,某些类型Object
会满足演员,即class organism//Organism class
{
...
void org_reproduce(string map[70][70], std::vector<organism>& childs)//If organism of opposite sex exists in a movable to space, make another organism
{
if(shouldReproduce)
{
organism child;
// initialize as desired
child.sex = rand(...) // randomize sex
child.age = 1;
child.hunger = ?;
child.x = this.x;
child.y = this.y;
childs.emplace_back(child);
}
}//End of func
为int main()
{ //Defining variables
string map[70][70];
srand(time(NULL));
std::vector<organism> allOrganisms;
// add some initial organisms
....
// loop that gives organisms life
while(true)
{
std::vector<organism> childs;
for(organism& org : allOrganisms)
{
// call all kinds of moving and etc. functions on org
...
// time to reproduce
org.org_reproduce(map, childs);
}
// add all childs to the herd
allOrganisms.insert(allOrganisms.end(), childs.begin(), childs.end());
}
return 0;
}
时。
有关此内容的背景阅读,请参阅:Liskov substitution principle,其中涉及函数的子类型。