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



我一直在尝试理解类型检查和类型转换。我已经了解了使用泛型对集合进行类型转换的概念,但是泛型在哪里允许强类型检查除集合以外的非法类型转换。有人可以给我一个示例,其中在编译时存在类型转换错误,泛型可以有效地处理这个问题。

提前致谢

以这个案例为例:

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步骤不会引发编译时错误,这可能会导致以后出现问题。

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

集合

之外的示例之一是当类实现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) {
        // ...
    }
}    

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

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)

因此,编译器在检查输入和输出是否属于正确的类型方面几乎不会提供任何帮助,从而迫使人们在运行时执行可能不安全的类型转换。

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

最新更新