理解Java泛型 通配符 ? 以及其使用
什么是泛型:
泛型从字面上理解,是指一个类、接口或方法支持多种类型,使之广泛化、一般化和更加通用。Java中使用Object类来定义类型也 能实现泛型,但缺点是造成原类型信息的丢失,在使用中容易造成ClassCastException。
Java泛型带到的好处:
- 使得一个类或方法中的类型参数化,最终达到代码复用的效果。( 不使用泛型,你可能需要每种情况的类或方法都要定义一遍 )
- 实现类型检查的功能,避免ClassCastException。(这是相对于使用Object类型实现泛型而言。因为我可以每个类都定义一遍来实现所谓的类型检查。)
泛型自定义:类、接口、方法
//定义泛型类,接口的定义和类一样
class G1<T> {
T content;
} // 定义泛型方法,方法的头部使用<T>声明,注意结构
class GMethod1 { // 一般泛型方法定义
public static <T> void method1(T params) { } // 返回值也为泛型
public static <E> E method2(E params) {
E content = params;
return content;
} } // extends 的使用,限定泛型的范围,等于或者是extends的子类;只有extends,没有super,通配符才有extends和super
class G2<T extends Number> {
T content;
}
泛型的使用
//泛型类或接口的使用
List<String> list = new ArrayList<>(); //泛型方法的使用,在方法前面使用<>传入类型
<String>gMethod1.method1("str");
<Integer>gMethod1.method1(new Integer(1)); //如果入参的参数中使用了T,则可以省略方法前面的<>,编译器可以自行识别出其类型
gMethod1.method1("str");
gMethod1.method1(new Integer(1));
通配符?
什么时候会用通配符:
通配符只有在修饰一个变量时会用到,使用它可方便地引用包含了多种类型的泛型;
public static void main() {
//不使用通配符
ArrayList<Object> arr = new ArrayList<Object>();
// ArrayList<Object> arr = new ArrayList<String>(); 编译不通过,arr只能引用包含Object的集合
//使用通配符
ArrayList<?> arr2;
arr2 = new ArrayList<String>();
arr2 = new ArrayList<Integer>();
arr2.get(0); //返回的,是一个Object对象,通配符会使原集合包含类型信息丢失,也是通配符的使用代价
// 通常在方法参数中才会使用通配符,使得这个方法可以引用多种泛型集合。这个和范型方法不一样,这里只是一个引用变量
void gMethod(ArrayList<? extends Number> param) {
}
可以看到,通配符使用方便的同时,使原集合包含类型信息丢失。
通配符的extends super关键字
详解:https://blog.csdn.net/qq_35923521/article/details/77717308
ArrayList<? extends Number> arr3; // Number 是 Integer、Float的父类; ArrayList<Number> arr3只能引用 ArrayList<Number>
arr3 = new ArrayList<Integer>();
arr3 = new ArrayList<Float>();
// arr3 = new ArrayList<String>(); 编译不通过,String 和 Number不存在继承关系 arr3.get(0); //返回的,是一个Number对象
arr3.add(null); //使用过通配符修饰的集合变量,只能add(null),因为这个集合中包含的类型已经确定,只是类型信息已经丢失了,add(Object)也不行
无限定通配符?
ArrayList<?> arr3; 无通配符等同于 ArrayList<? extends Object> arr3; //用于取值get(),不能赋值set()
扩展:不使用泛型的变量和另一种方式
//这样使用功能和通配符一样,可以多种引用,但一般不推荐这样使用
ArrayList a4;
a4 = new ArrayList<String>();
a4 = new ArrayList<Integer>();
a4.add(new Integer(1));
a4.add(new String("str"));//和通配符引用不能add不一样,这样方式可以add多种类型元素,但一般不推荐 a4.get(0); //返回的,是一个Object对象
理解Java泛型 通配符 ? 以及其使用的更多相关文章
- Java 干货之深入理解Java泛型
一般的类和方法,只能使用具体的类型,要么是基本类型,要么是自定义的类.如果要编写可以应用多中类型的代码,这种刻板的限制对代码得束缚会就会很大. ---<Thinking in Java> ...
- Java 泛型 通配符类型
Java 泛型 通配符类型 @author ixenos 摘要:限定通配符类型.无限定通配符类型.与普通泛型区别.通配符捕获 通配符类型 通配符的子类型限定(?都是儿孙) <? extends ...
- 转:理解Java泛型
JDK 5.0 中增加的泛型类型,是 Java 语言中类型安全的一次重要改进.但是,对于初次使用泛型类型的用户来说,泛型的某些方面看起来可能不容易明白,甚至非常奇怪.在本月的“Java 理论和实践”中 ...
- [转]JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别
原文地址:https://www.jianshu.com/p/95f349258afb 1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被 ...
- java泛型通配符?
转自:http://www.linuxidc.com/Linux/2013-10/90928.htm T 有类型 ? 未知类型 一.通配符的上界 既然知道List<Cat>并不是Lis ...
- 深入理解java泛型
一. 什么是泛型? 泛 型(Generic type 或者 generics)是对 简单的理解,就是对类型的参数化,比如我们定义一个类属性或者实例属性时,往往要指定具体的类型,如Integer.Per ...
- JAVA泛型通配符T,E,K,V区别,T以及Class<T>,Class<?>的区别
1. 先解释下泛型概念 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛 ...
- Java泛型 通配符? extends与super
Java 泛型 关键字说明 ? 通配符类型 <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类 <? super T> 表示类型下界(Java ...
- JAVA 泛型 通配符? extends super限定,实例区分extends super限定的作用用法
java泛型中的关键字 ? 表示通配符类型 <? extends T> 既然是extends,就是表示泛型参数类型的上界,说明参数的类型应该是T或者T的子类. <? super T& ...
随机推荐
- php正则表达式取子字符串及替换
最近在学习如何用php编写cms,想把文章中的第一个图片提取出来当做缩略图显示到前面,想到的方法就是把文章内容作为一个大字符串,然后用正则表达式找出匹配出第一次出现<img src=" ...
- mongoDb学习以及spring管理 (包括百度云配置)
1.windows下的安装http://www.cnblogs.com/liuzhiying/p/5915741.html 2.慕课网学习单机操作mongoDb 赋权限:http://blog.csd ...
- iframe 实现网页本页显示
<el-dialog title="" :visible.sync="dialogVisible"> <iframe src="ht ...
- hdu3076--ssworld VS DDD(概率dp第三弹,求概率)
ssworld VS DDD Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) T ...
- STL源代码剖析 容器 stl_vector.h
本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie vector --------------------------------------- ...
- java获取网页源码
获取网页的源码: package com.atguigu.crud.controller; import java.io.BufferedReader; import java.io.Buffered ...
- 1verilog 位拼接
位拼接还可以用重复法来简化表达式.见下例: {4{w}} //这等同于{w,w,w,w} 位拼接还可以用嵌套的方式来表达.见下例: {b,{3{a,b}}} //这等同 ...
- 【WPF学习笔记】之如何通过后台C#代码添加(增/删/改按钮)实现对SQLServer数据库数据的更改
首先,需要连接SQLServer数据库的服务器名称server.数据库名database.数据库用户名uid以及密码pwd,如下图: 然后需要以下数据库SQL代码段,还有一个myHelper.cs代码 ...
- Linux下服务端口被占用
有一次,在启动ejabberd的时候,报错如下: 10:30:15 =CRASH REPORT==== crasher: initial call: supervisor:ejabberd_liste ...
- linux环境tomcat配置及hadoop 2.6伪分布模式安装配置
一.ubuntu 15.04.openjdk1.7.tomcat7环境配置 1. 配置openjdk1.7,输入命令: -jdk 2. 查看java是否安装成功,输入命令: envjava -vers ...