泛型类型限定和通配符类型限定

泛型类型变量的限定

泛型的基础知识可以参考其他教程。

如果在方法前指定了<T>,那么就是说,方法的这个泛型类型和类定义时的泛型类型无关,这个特性让泛型方法可以定义在普通类中而不是泛型类中。

我们都知道,泛型中可以限定类型变量必须实现某几个接口或者继承某个类,多个限定类型用&分隔,类必须放在限定列表中所有接口的前面。例如:

[java] view plain copy

print?

  1. import java.io.Serializable;
  2. /**
  3. * ICE
  4. * 2016/10/17 0017 14:12
  5. */
  6. public class Demo {
  7. public static void main(String[] args) {
  8. D<A> d = new D<>();
  9. A a = new A();
  10. d.test1(a);
  11. B b = new B();
  12. d.test1(b);
  13. C c = new C();
  14. d.test1(c);
  15. d.test2("test");
  16. }
  17. }
  18. class A implements Serializable, Cloneable {
  19. @Override
  20. public String toString() {
  21. return "A{}";
  22. }
  23. }
  24. class B extends A {
  25. @Override
  26. public String toString() {
  27. return "B{}";
  28. }
  29. }
  30. class C extends A {
  31. @Override
  32. public String toString() {
  33. return "C{}";
  34. }
  35. }
  36. class D<T extends A & Serializable & Cloneable> {
  37. public void test1(T t) {
  38. System.out.println(t);
  39. }
  40. public <T> void test2(T t) {
  41. System.out.println(t);
  42. }
  43. }

输出:

[plain] view plain copy

print?

  1. A{}
  2. B{}
  3. C{}
  4. test

通配符类型

通配符“?”同样可以对类型进行限定。可以分为子类型限定、超类型限定和无限定。通配符不是类型变量,因此不能在代码中使用"?"作为一种类型。

子类型限定

表示类型的上界,类似泛型的类型变量限定,格式是:? extends X。

特点:

1、限定为X和X的子类型,但不知道具体是哪个子类型,可能是怕导致类型转换错误(比如向下转型时编译不会报错,但是如果超类引用不是指向子类对象,那么运行时会报错),所以作为方法的参数时,这里禁止传递特定的类型。

2、作为方法的参数时,可以传递null。

作用:主要用来安全地访问数据,可以访问X及其子类型。

[java] view plain copy

print?

  1. import java.util.ArrayList;
  2. import java.util.List;
  3. /**
  4. * ICE
  5. * 2016/10/17 0017 14:12
  6. */
  7. public class Demo {
  8. public static void main(String[] args) {
  9. A a = new A();
  10. B b = new B();
  11. C c = new C();
  12. List<A> list = new ArrayList<>();
  13. list.add(a);
  14. list.add(b);
  15. list.add(c);
  16. //根据list的值,我们可以给列表中的对象做<? extends A>限定,因为都是A和A的子类,get返回值赋给A是完全合法的
  17. List<? extends A> list1 = list;
  18. list.add(null);
  19. for (int i = 0; i < list1.size(); i++) {
  20. A a1 = list1.get(i);
  21. System.out.println(a1);
  22. }
  23. //这里如果set任何非null的值,编译器都会报错
  24. D<? extends A> d = new D<>();
  25. d.set(null);
  26. }
  27. }
  28. class A {
  29. @Override
  30. public String toString() {
  31. return "A{}";
  32. }
  33. }
  34. class B extends A {
  35. @Override
  36. public String toString() {
  37. return "B{}";
  38. }
  39. }
  40. class C extends A {
  41. @Override
  42. public String toString() {
  43. return "C{}";
  44. }
  45. }
  46. class D<T> {
  47. public void test1(T t) {
  48. System.out.println(t);
  49. }
  50. public void set(T t) {
  51. }
  52. }

输出:

[plain] view plain copy

print?

  1. A{}
  2. B{}
  3. C{}
  4. null

超类型限定

表示类型的下界,格式是:? super X。

特点:

1、限定为X和X的超类型,直至Object类,因为不知道具体是哪个超类型,因此方法返回的类型只能赋给Object。

2、因为可以向上转型,所以作为方法的参数时,可以传递X以及X的子类型。

3、作为方法的参数时,可以传递null。

作用:主要用来安全地写入数据,可以写入X及其子类型。

[java] view plain copy

print?

  1. /**
  2. * ICE
  3. * 2016/10/17 0017 14:12
  4. */
  5. public class Demo {
  6. public static void main(String[] args) {
  7. A a = new A();
  8. B b = new B();
  9. C c = new C();
  10. D<? super A> d = new D<>();
  11. Object o = d.get();
  12. d.set(a);
  13. d.set(b);
  14. d.set(c);
  15. d.set(null);
  16. }
  17. }
  18. class A {
  19. @Override
  20. public String toString() {
  21. return "A{}";
  22. }
  23. }
  24. class B extends A {
  25. @Override
  26. public String toString() {
  27. return "B{}";
  28. }
  29. }
  30. class C extends A {
  31. @Override
  32. public String toString() {
  33. return "C{}";
  34. }
  35. }
  36. class D<T> {
  37. public void set(T t) {
  38. }
  39. public T get() {
  40. return null;
  41. }
  42. }

无限定

无限定不等于可以传任何值,相反,作为方法的参数时,只能传递null,作为方法的返回时,只能赋给Object。

[java] view plain copy

print?

  1. /**
  2. * ICE
  3. * 2016/10/17 0017 14:12
  4. */
  5. public class Demo {
  6. public static void main(String[] args) {
  7. D<?> d = new D<>();
  8. Object o = d.get();
  9. d.set(null);
  10. }
  11. }
  12. class A {
  13. @Override
  14. public String toString() {
  15. return "A{}";
  16. }
  17. }
  18. class B extends A {
  19. @Override
  20. public String toString() {
  21. return "B{}";
  22. }
  23. }
  24. class C extends A {
  25. @Override
  26. public String toString() {
  27. return "C{}";
  28. }
  29. }
  30. class D<T> {
  31. public void set(T t) {
  32. }
  33. public T get() {
  34. return null;
  35. }
  36. }

有什么作用呢?对于一些简单的操作比如不需要实际类型的方法,就显得比泛型方法简洁。

[java] view plain copy

print?

    1. /**
    2. * ICE
    3. * 2016/10/17 0017 14:12
    4. */
    5. public class Demo {
    6. public static void test(D<?> d) {
    7. System.out.println(d == null);
    8. }
    9. public static <T> void test1(D<T> d) {
    10. System.out.println(d == null);
    11. }
    12. public static void main(String[] args) {
    13. D d = new D();
    14. Demo.test(d);
    15. Demo.test1(d);
    16. }
    17. }
    18. class D<T> {
    19. }
时间: 2024-10-17 23:52:14

泛型类型限定和通配符类型限定的相关文章

const 不兼容的类型限定符问题

今天遇到一个问题,const对象调用成员函数的时候提示"不兼容的类型限定符"问题,查了一些资料,解决办法: 在成员函数后面加上 const关键字,例如: int get() const { return x; } 更进一步的原因是:const限定的对象以及其引用只能调用const限定的成员函数. const限定代表变量的值不会发生改变,要想不改变变量的值则只能调用const修饰的成员函数. 之前没有注意,mark一下.

2 C语言 常量,进制,类型限定 输入输出 运算符 类型转换

常量:#define const 字符串常量 1 8 10 16 进制转换 sizeof关键字 变量 int folat char 类型限定 const volatile register 输入输出 printf scanf 运算符 = + - *  / % += -= *= /= %= ++ -- , 运算符优先级 代码块{} 类型转换 1         C语言中的数据类型 1.1      常量 常量就是在程序中不可变化的量,常量是不可被赋值的. 1.1.1         #define

Java 通配符类型

Java 通配符类型 @author ixenos 通配符类型 通配符的子类型限定(?都是儿孙) <? extends T> Pair<? extends Employee> managerrr = new Pair<Manager>(ceo,cfo); //Manager是Employee子类,这里协变了(泛型的通配符类型可协变,而一般的泛型不可协变) 类型Pair<? extends Employee>的方法: //?是Manager的子类们 void

背水一战 Windows 10 (9) - 资源: 资源限定符概述, 资源限定符示例

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 资源 资源限定符概述 资源限定符示例 示例1.资源限定符概述Resource/Qualifiers/Summary.xaml <Page x:Class="Windows10.Resource.Qualifiers.Summary" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x=&qu

资源: 资源限定符概述, 资源限定符示例

资源限定符概述 资源限定符示例 示例1.资源限定符概述Resource/Qualifiers/Summary.xaml <Page x:Class="Windows10.Resource.Qualifiers.Summary" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/200

Java泛型通配符以及限定

摘抄笔记 A:泛型的限定 /* * 将的酒店员工,厨师,服务员,经理,分别存储到3个集合中 * 定义方法,可以同时遍历3集合,遍历三个集合的同时,可以调用工作方法 */ import java.util.ArrayList; import java.util.Iterator; public class GenericTest { public static void main(String[] args) { //创建3个集合对象 ArrayList<ChuShi> cs = new Arr

php 的函数参数值类型限定

如例: function test(array $a,test $b){ /*...*/ } class test{ /*...*/ } test(array(),new test); 表示test函数的参数里,第一个参数必须是数组,第二个必须是test类的实体.php没有别的限定类型了,诸如string.integer这样的限定类型是没有的,只有数组和对象两种限定类型.

类型限定符volatile

volatile bool flag; volatile int a; 添加volatile限定符的变量会获得几个特性: 1.强制内存读取 因为这个数据是"易变的(volatile)",所以要时刻关注,不能偷懒 场景: 把内存中的变量拷贝到寄存器中进行处理以加快速度: 存在的问题: 是对变量的拷贝进行处理,而变量本体如果发生变化可能也不会察觉 解决: 加上volatile限定符后,每次处理都会直接从内存读取,所以可以感知变量的变化. 但是: 寄存器走了,缓存来了,但问题没那么严重 多核

python限定方法参数类型、返回值类型、变量类型等

typing模块的作用 自python3.5开始,PEP484为python引入了类型注解(type hints) 类型检查,防止运行时出现参数和返回值类型.变量类型不符合. 作为开发文档附加说明,方便使用者调用时传入和返回参数类型. 该模块加入后并不会影响程序的运行,不会报正式的错误,只有提醒pycharm目前支持typing检查,参数类型错误会黄色提示 常用类型 int,long,float: 整型,长整形,浮点型 bool,str: 布尔型,字符串类型 List, Tuple, Dict,