Java 泛型(generics)详解及代码示例、Java 类型通配符详解及代码示例

- 概念
  • Java 泛型(generics)是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。
  • java中使用泛型举例:
    • List接口也使用了泛型:
    • ArrayList 是泛型类。
- 泛型标记符:
  • Java中的泛型标记符有:
    1、E - Element (在集合中使用,因为集合中存放的是元素)
    2、T - Type(Java 类)
    3、K - Key(键)
    4、V - Value(值)
    5、N - Number(数值类型)
    6、? - 表示不确定的 java 类型
- 泛型分类
  • 泛型方法
  • 泛型类
- 泛型方法:
  • 泛型方法在调用时可以接收不同类型的参数。根据传递给泛型方法的参数类型,编译器适当地处理每一个方法调用。定义泛型方法的规则如下:
    1、所有泛型方法声明都有一个类型参数声明部分(由尖括号分隔),该类型参数声明部分在方法返回类型之前(在下面例子中的 )。
    2、每一个类型参数声明部分包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。
    3、类型参数能被用来声明返回值类型,并且能作为泛型方法得到的实际参数类型的占位符。
    4、泛型方法体的声明和其他方法一样。注意类型参数只能代表引用型类型,不能是原始类型(像 int、double、char 等)。

  • 泛型方法代码示例:

//collectionReverse.java
import java.util.Arrays;
import java.util.Collections;public class GenericMethodDemo {public static <E> void collectionReverse(E[] colArray){Collections.reverse(Arrays.asList(colArray));System.out.println("逆序后的集合的排列顺序为:"+Arrays.toString(colArray));}public static void main(String[] args) {Integer[] i = {1, 2, 3, 4, 5};Character[] c = {'G', 'e', 'n', 'e', 'r', 'i', 'c'};String[] s = {"first", "second", "third", "fourth", "fifth"};System.out.println("原序集合顺序为:"+Arrays.toString(i));collectionReverse(i);System.out.println("--------------------------------------");System.out.println("原序集合顺序为:"+Arrays.toString(c));collectionReverse(c);System.out.println("--------------------------------------");System.out.println("原序集合顺序为:"+Arrays.toString(s));collectionReverse(s);}}//执行结果如下:
//原序集合顺序为:[1, 2, 3, 4, 5]
//逆序后的集合的排列顺序为:[5, 4, 3, 2, 1]
//--------------------------------------
//原序集合顺序为:[G, e, n, e, r, i, c]
//逆序后的集合的排列顺序为:[c, i, r, e, n, e, G]
//--------------------------------------
//原序集合顺序为:[first, second, third, fourth, fifth]
//逆序后的集合的排列顺序为:[fifth, fourth, third, second, first]//Process finished with exit code 0
  • 有界的类型参数:
    可能有时候,你会想限制那些被允许传递到一个类型参数的类型种类范围。例如,一个操作数字的方法可能只希望接受Number或者Number子类的实例。这就是有界类型参数的目的。要声明一个有界的类型参数,首先列出类型参数的名称,后跟extends关键字,最后紧跟它的上界。
  • 有界的类型参数代码示例:
//BoundedGenericMethodDemo.java
import java.util.Arrays;
import java.util.Collections;public class BoundedGenericMethodDemo {public static <E extends Number> void collectionReverse(E[] colArray){Collections.reverse(Arrays.asList(colArray));System.out.println("逆序后的集合的排列顺序为:"+Arrays.toString(colArray));}public static void main(String[] args) {Integer[] i = {1, 2, 3, 4, 5};Character[] c = {'G', 'e', 'n', 'e', 'r', 'i', 'c'};String[] s = {"first", "second", "third", "fourth", "fifth"};System.out.println("原序集合顺序为:"+Arrays.toString(i));collectionReverse(i);System.out.println("--------------------------------------");System.out.println("原序集合顺序为:"+Arrays.toString(c));collectionReverse(c);System.out.println("--------------------------------------");System.out.println("原序集合顺序为:"+Arrays.toString(s));collectionReverse(s);}}//执行结果如下,由于定义了类型上限,即调用泛型方法传递的参数必须是Number 类的子类,所以传递Character[] 和 String[] 都会报错。将collectionReverse(c) 和 collectionReverse(s) 两行代码注释掉即可:
//java: 无法将类 com.example.utils.generic.BoundedGenericMethodDemo中的方法 collectionReverse应用到给定类型;
//  需要: E[]
//  找到: java.lang.Character[]
//  原因: 推断类型不符合上限
//    推断: java.lang.Character
//    上限: java.lang.Number
- 泛型类
  • 泛型类的声明和非泛型类的声明类似,除了在类名后面添加了类型参数声明部分。和泛型方法一样,泛型类的类型参数声明部分也包含一个或多个类型参数,参数间用逗号隔开。一个泛型参数,也被称为一个类型变量,是用于指定一个泛型类型名称的标识符。因为他们接受一个或多个参数,这些类被称为参数化的类或参数化的类型。
  • 泛型类代码示例:
//GenericClassDemo.java
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;public class GenericClassDemo<K, V> {private K k;private V v;public void put(K k, V v){this.k = k;this.v = v;}public V get(K k){return v;}public static void main(String[] args) {GenericClassDemo<String, Character[]> gcd = new GenericClassDemo<>();gcd.put("java_say", new Character[]{'h','e','l','l','o','泛','型','类'});Character[] java_says = gcd.get("java_say");System.out.println("打印出来的值为:"+Arrays.toString(java_says));}}//执行结果如下:
//打印出来的值为:[h, e, l, l, o, 泛, 型, 类]//Process finished with exit code 0
- 类型通配符
  • 类型通配符一般是使用 ? 代替具体的类型参数。例如 List<?> 在逻辑上是 List<String>, List<Integer> 等所有 List<具体类型实参> 的父类。
  • 只有泛型类的类型参数可以使用 ? 类型通配符来替换。代码示例如下:
//GenericClassBox.java
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class GenericClassBox<K, V> {private K k;private V v;public void put(K k, V v){this.k = k;this.v = v;}public V get(K k){return v;}public static void main(String[] args) {GenericClassBox<String, String> gcd1 = new GenericClassBox<>();gcd1.put("java_say","hello, 类型通配符");GenericClassBox<Integer, Integer> gcd2 = new GenericClassBox<>();gcd2.put(2,2);GenericClassBox<Character, String> gcd3 = new GenericClassBox<>();gcd3.put(new Character('a'), "bc");getValue(gcd1);System.out.println("--------------------------");getValue(gcd2);System.out.println("--------------------------");getValue(gcd3);}public static void getValue(GenericClassBox<?,?> data){System.out.println("使用通配符获取到的值为:"+data.v);}}//执行结果如下:
//使用通配符获取到的值为:hello, 类型通配符
//--------------------------
//使用通配符获取到的值为:2
//--------------------------
//使用通配符获取到的值为:bc//Process finished with exit code 0
  • 有界的类型通配符:
    1、<? extends T>表示该通配符所代表的类型是T类型的子类。
    2、<? super T>表示该通配符所代表的类型是T类型的父类。

  • 有界的类型通配符代码示例:

//BoundedGenericClassBox.java
public class BoundedGenericClassBox<K, V> {private K k;private V v;public void put(K k, V v){this.k = k;this.v = v;}public V get(K k){return v;}public static void main(String[] args) {BoundedGenericClassBox<Integer, String> gcd1 = new BoundedGenericClassBox<>();gcd1.put(1,"hello, 有界的类型通配符");getValue(gcd1);}public static void getValue(BoundedGenericClassBox<? extends Number,? super String> data){//第一个类型通配符 ? 代表的类型必须是Number的子类//第二个类型通配符 ? 代表的类型必须是String的父类System.out.println("使用有界的通配符获取到的值为:"+data.v);}}//执行结果如下:
//使用有界的通配符获取到的值为:hello, 有界的类型通配符//Process finished with exit code 0

Java 泛型(generics)详解及代码示例、Java 类型通配符详解及代码示例相关推荐

  1. Java 泛型(Generics) 综述

    一. 引子 一般的类和方法,只能使用具体类型:要么是基本类型,要么是自定义类型.如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大. 多态 算是一种泛化机制,但对代码的约束还是太强 ...

  2. Java泛型Generics

    转载请标明出处: http://blog.csdn.net/wu_wxc/article/details/51493181 本文出自[吴孝城的CSDN博客] 泛型 泛型是JDK 5中引入的一个新特性 ...

  3. Java 泛型 (generics) 的使用

    泛型是JDK1.5以后增加的,它可以帮助我们建立类型安全的集合.在使用了泛型的集合中,遍历时不必进行强制类型转换.JDK提供了支持泛型的编译器,将运行时的类型检查提前到了编译时执行,提高了代码可读性和 ...

  4. [转载] JAVA泛型杂谈--擦除,协变,逆变,通配符等

    参考链接: Java中的协变返回类型 在<JAVA核心思想>这本书里,关于泛型的章节意外的很多,小小的泛型里其实有很多可以学习的内容,我总结下最近看书的成果. 一. 泛型的好处和应用 最基 ...

  5. Java泛型(类、接口、方法)及通配符

    什么是泛型? 泛型,即"参数化类型".例如:定义方法时有形参,然后调用此方法时传递实参.参数化类型就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形 ...

  6. java解包_Java的原始类型自动包装与解包机制

    java5之后对原始数据类型如int.char.long等基本数据类型有自动打包成相应的复合类型Integer.Character.Long等的机制:也可以将复合类型自动转换为原始类型. 这取决于程序 ...

  7. java 泛型全解 - 绝对最详细

    背景 对于java的泛型我一直属于一知半解的,平常真心用的不多.直到阅读<Effect Java>,看到很多平常不了解的用法,才下定决心,需要系统的学习,并且记录下来. 1.泛型的概述: ...

  8. java泛型常用特点_?你必须知道的Java泛型

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin3923282... 种一棵树最好的时间是十年前,其次是现在 我知道很多人不玩qq了,但是怀旧一下,欢 ...

  9. java 泛型参数_Java泛型

    一.概述 Java泛型(generics)是JDK 5中引入的一个新特性,泛型提供了编译时类型安全监测机制,该机制允许程序员在编译时监测非法的类型.使用泛型机制编写的程序代码要比那些杂乱地使用Obje ...

最新文章

  1. 加拿大留学|电气工程/计算机工程/计算机科学,傻傻分不清
  2. java并发性是指什么_java – 什么是“非阻塞”并发,它与普通并发性有什么不同?...
  3. python numpy中stack(),hstack(),vstack()函数解释
  4. Python10分钟入门
  5. 《MySQL8.0.22:Lock(锁)知识总结以及源码分析》
  6. 赫胥黎的焦虑与美丽新世界
  7. linux+系统优化基础,Linux入门基础(三):Linux用户及权限基础
  8. android 9宫格输入法,Android/WP原生九宫格输入法对比_诺基亚 Lumia 925_手机iOS频道-中关村在线...
  9. 非Json字符串转map对象
  10. 计蒜客-----泥塑课(set)
  11. 自定义 View 之圆形、圆角、爱心、动态旗帜等图片效果
  12. 深度学习对抗样本的防御方法
  13. 《汉信码》——中国首个完全自主知识产权二维条码国家标准颁布
  14. 设置大小合适的Win7休眠文件Hiberfil.SYS
  15. 香农采样定理和奈奎斯特采样定理
  16. BEA-3XXXXX错误代码
  17. 群晖|半洗白后moments正常显示人像、主题、预览
  18. usd to php exchange,USD to PHP
  19. python学习Day-8
  20. stata最大值最小值命令_Stata: 双栏模型简介 (Doublehurdle model)

热门文章

  1. Autosar NM : 网络是如何被唤醒的<一>
  2. 01背包问题(状态转移方程讲解)
  3. Data truncation: Truncated incorrect DOUBLE value:,
  4. pxcook(像素大厨)安装--
  5. 马斯克斥资440亿美元入主推特:立马踢走CEO和CFO
  6. Reshape的命令应用
  7. mac导入电子书或文档到kindle
  8. 【转】为何有的职业后期不给力?
  9. After Effects动态图形和数据可视化
  10. 社群助手可以做哪些工作?