为什么UnaryFunction <object>可以转换为UnaryFunction <t>?

时间:2016-09-10 06:42:51

标签: java generics effective-java

当我阅读 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>

1 个答案:

答案 0 :(得分:4)

由于类型擦除,没有绑定(... extends ...)的所有泛型类型都被视为Object。因此,此强制转换可能对T的某些值有效。@SuppressWarnings("unchecked")告诉编译器你正在做正确的事情,所以警告被抑制。

投射到特定类型是有问题的。我们假设您正在处理List<Object>,其中List<A> AA类。在这种情况下,列表可能包含UnaryFunction<Object>的超类型的元素,因此这个强制转换是不合理的,因此编译器不允许它。在函数(IDENTITY = t -> new Object();)的情况下,暗示它可以返回一个Object。假设您的代码为UnaryFunction<A>,在这种情况下,转换为Object会导致UnaryFunction<T>不正确。在TT的情况下,某些类型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,其中涉及函数的子类型。