Java核心技术知识点笔记—泛型程序设计(四)

前言:固定的泛型类型系统使用起来并没有想象中的愉快,Java设计者发明了一种巧妙的(安全的)“解决方案”:通配符类型。

1、泛型类型的继承规则:有一个泛型类

public class TestGenericC {
    ...
}

记住,不管S和T有什么联系,TestGenericC和TestGenericC没有任何关系。

2、通配符类型

2.1、概念:通配符类型允许类型参数变化。假设有两个相互继承的类:

public class TestA {

    private String paramsA;

    public void setParamsA(String paramsA) {
        this.paramsA = paramsA;
    }

    public String getParamsA() {
        return paramsA;
    }
}

public class TestB extends TestA{

    private String paramsB;

    public void setParamsB(String paramsB) {
        this.paramsB = paramsB;
    }

    public String getParamsB() {
        return paramsB;
    }
}

此时定义一个方法:

    public static void test(ArrayList c) {
        System.out.print(c.get(0).getParamsA());
    }

根据泛型继承规则,无法将ArrayList传递给这个方法。使用通配符类型可以解决这个问题。

   public static void test(ArrayList c) {
        System.out.print(c.get(0).getParamsA());
    }

这里,使用get()方法是没有问题的,但是,如果要对c使用add或set方法,依然会出现报错。原因在于,当深入查看ArrayList时,其方法类似于:

? extends TestA get()

void set(? extends TestA)

使用get方法没有问题,将返回值赋值给一个TestA的引用完全合法。但set方法里面,编译器只知道需要某个TestA的子类型,但却不知道具体的类型是什么。

2.2、通配符的超类型限定:

通配符限定与类型变量限定类似,但通配符还可以指定一个超类型限定(supertype bound),即

? super 类型X,这个通配符限制为“类型X”的所有超类型。带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。

2.3、无限定通配符:例如TestA。(一个例子展示,这种写法是错误的)

public class TestA{

    private String paramsA;

    public void setParamsA(? paramsA) {

        this.paramsA = paramsA;
    }

    public ? getParamsA() {
        return paramsA;
    }

}

假设上述代码正常,但getParamsA方法只能赋值给一个Object。setParamsA则无法调用,甚至使用Object作为参数都不行。

你可能感兴趣的:(Java,java,泛型,通配符)