Generics如何在编译时允许对类型转换错误进行强类型检查

时间:2013-09-13 08:27:42

标签: java generics casting

我一直在努力理解类型检查和类型转换。我已经理解了使用Generics对集合进行类型转换的概念,但Generics允许强类型检查除集合之外的非法类型转换。有人可以为我提供一个示例,其中在编译期间存在类型转换错误,并且泛型有效地处理此问题。

提前致谢

4 个答案:

答案 0 :(得分:1)

以这种情况为例:

public class Test {
    public static void main(String[] args) {
        Pair<Integer, Integer> p1 = new Pair<Integer, Integer>(3, 5);
        Pair<String, Integer> p2 = (Pair<String, Integer>) p1;

        Pair p = new Pair<Integer, Integer>(3, 5);
        Pair<String, Integer> p3 = (Pair<String, Integer>) p;
    }

    static class Pair<A, B> {
        A first;
        B second;

        public Pair(A a, B b) {
            first = a;
            second = b;
        }
    }
}

由于泛型,Pair<String, Integer> p2 = (Pair<String, Integer>) p1会引发编译错误。

但由于p不使用泛型,因此p3 = (Pair<String, Integer>) p步骤不会抛出编译时错误,这可能会导致以后出现问题。

答案 1 :(得分:0)

JPA在TypedQuery中使用泛型来确保返回预期的类型。如果您要求Customer,则类型系统知道将查询结果视为Customer个对象而不是您必须自己投射的普通Object,如果您使用Criteria API,它还可以验证您的查询参数是否引用Customer类的有效属性。

答案 2 :(得分:0)

集合之外的一个示例是类实现generic接口时。例如,Comparable<T>Integer实现为

Integer implements Comparable<Integer>

确保只能将Integer个实例与Integer进行比较。

泛型 compareTo()方法在接口中定义为

public interface Comparable<T> {    
    public int compareTo(T o);
}

Integer类将其实现为

public class Integer implements Comparable<Integer> {
    // ...
    public int compareTo(Integer anotherInteger) {
        // ...
    }
}    

答案 3 :(得分:0)

一个非常基本的例子是构建对象的抽象类:

public abstract class BuilderBase<T, P> {
    public T build(P parameter);
}

实现可能类似于

public class IntBuilder extends BuilderBase<Integer, String> {
    public Integer build(String parameter) {
        return Integer.parse(parameter);
    }
}

如果没有泛型,build签名必须是

public Object build(Object parameter)

因此,编译器在检查输入和输出是否为正确类型时几乎没有帮助,迫使人们在运行时进行潜在的不安全的类型转换。

(免责声明:由于协方差和原因,这有点过于简单了。)