Java语法基础学习DayTwelve(泛型)
一、泛型(Generic)在集合中的使用
1.作用
(1)解决元素存储的安全问题
(2)解决获取数据元素时,需要类型强转的问题
2.代码案例
//在集合没有使用泛型的情况下
List list = new ArrayList();
//list用来存放成绩
list.add();
list.add();
list.add();
//在没有使用泛型时,任何Object及其子类都可以添加进来,不安全
list.add(new String("AA")); for(int i = ; i < list.size();i++){
//在强转字符串“AA”为int型时报ClassCastException的异常
int score = (Integer)list.get(i);
System.out.println(score);
}
//在集合中使用泛型
List<Integer> list = new ArrayList<Integer>();
//list用来存放成绩
list.add();
list.add();
list.add();
//list.add(new String("AA"));编译时就不通过,只能添加Integer类型的元素 Iterator<Integer> it = list.iterator();//用Iterator也需要声明泛型为Integer
while(it.hasNext()){
System.out.println(it.next());
}
二、自定义泛型类、泛型接口、泛型方法
1.特点
(1)当实例化泛型类的对象时,指明泛型的类型,对应的类中所有使用泛型的位置,都变为指定的类型
(2)如果泛型类在实例化时没有指明泛型的类型,默认为Object类
(3)通过对象调用泛型方法时,指明泛型的类型,这个类型可以和泛型类的泛型的类型不一致。
(4)静态方法中不能使用类的泛型(因为类的泛型在实例化才指明类型,所以不能在静态方法中使用)
(5)不能在try-catch中使用泛型
2.代码示例
//自定义泛型类
public class Order<T> {//实例化后,类中的所有T都变为指定的类型
private T t;
List<T> list = new ArrayList<>(); public void add(){
list.add(t);
}
public T getT(){
return t;
}
public void setT(T t){
this.t = t;
}
//声明一个泛型方法,实现任意类型的数组到集合的复制
public <E> List<E> fromArrayToList(E[] e,List<E> list){//注意“<E>”的位置,不能少
for(E e1 : e){
list.add(e1);
}
return list;
}
}
//继承泛型类或泛型接口时,可以指明泛型的类型,也可以不指明
class SubOrder extends Order<Integer>{//class SubOrder<T> extends Order<T>{} }
//泛型类的使用
public class TestGeneric{
public static void main(String[] args){
Order<Boolean> order = new Order<Boolean>();
order.setT(true);//参数只能是Boolean类型的
System.out.println(order.getT());//输出true
order.add();
List<Boolean> list = order.list;
System.out.println(list);//输出[true] SubOrder o1 = new SubOrder();
//只能用List<Integer>类型的List接收SubOrder类型的list。
List<Integer> list1 = o1.list; Integer[] i = new Integer[](,,);
List<Integer> list2 = new ArrayList<>();
List<Integer> list3 = order.fromArrayToList(i,list2);
System.out.println(list2);//输出[1,2,3]
System.out.println(list3);输出[,,]
}
}
三、泛型与继承的关系以及通配符
1.泛型与继承的关系:即使类A是类B的子类,List<A>也不是List<B>的子接口。
Object obj = null;
String str = "AA";
obj = str;//String是Object的子类,这么写没错 Object[] obj1 = null;
String[] str1 = new String[]("AA","BB","CC");
obj1 = str1;//也没错 List<Object> list = null;
List<String> list1 = new ArrayList<String>();
list = list1;//报错,类型不匹配
//用反证法,假设list = list1正确
//list.add(123);list可以传入Object类型的元素
//String str = list.get(0);//报错,所以假设不正确
2.通配符—— ?
(1)特点
A:List<A>、List<B>. . . . . .都是List<?>的子类
B:? extends A:可以存放A及其子类
C:? super A:可以存放A及其父类
List<?> list = null;
List<Object> list1 = new ArrayList<Object>();
List<String> list2 = new ArrayList<String>();
list = list1;//没错,LIst<?>是List<Object>的父类
list = list2;//没错,LIst<?>是List<String>的父类 List<? extends Number> list3 = null;
LIst<Integer> list4 = null;
list3 = list4;//没错
list3 = list1;//报错,只能是Number或Number的子类
List<? super Number> list5 = null;
list5 = list1;//没错
(2)通配符的使用
List<String> list = new ArrayList<String>();
list.add("AA");
list.add("BB");
List<?> list1 = list;
//可以读取声明为通配符的集合类的对象
Iterator<?> iterator = list1.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());//把next()返回的值都看成是Object类型的,所以可以读取
}
//不允许向声明为通配符的集合类的对象写入对象,唯一例外的是null
list1.add("CC");//报错,不知道写入的是什么类型的对象
list1.add();//报错
list1.add(null);//正确
Java语法基础学习DayTwelve(泛型)的更多相关文章
- Java语法基础学习DayNineteen(反射机制)
一.Refection定义 1.概述 Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性 ...
- Java语法基础学习DayEighteen(常用类)
一.String类 1.特点 String代表不可变的字符序列,底层用char[]存放. String是final的. 2.内存解析 3.常用方法 int length() char charAt(i ...
- Java语法基础学习DaySeven
---恢复内容开始--- 一.包装类——Wrapper 1.定义:针对八种基本数据类型定义相应的引用类型——包装类(封装类) boolean——Boolean byte——Byte ...
- Java语法基础学习DaySix
一.JavaBean——可重用组件 1.JavaBean是指符合以下标准的Java类: (1)类是公共的 (2)有一个无参的公共的构造器 (3)有属性,且有对应的get.set方法 2.好处 用户可以 ...
- Java语法基础学习DayThree
一.流程控制语句补充 1.switch语句 格式: switch(表达式) { case 值1: 语句体1; break; case 值2: 语句体2; break; ... default: 语句体 ...
- Java语法基础学习DayTwentyOne(网络编程)
一.IP地址和端口号 1.作用 通过IP地址,唯一的定位互联网上一台主机. 端口号标识正在计算机上运行的进程,不同进程有不同的端口号,被规定为一个16位的整数0~65535,其中0~1023被预先定义 ...
- Java语法基础学习DayTwenty(反射机制续)
一.Java动态代理 1.代理设计模式的原理 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上. 2. ...
- Java语法基础学习DaySeventeen(多线程续)
一.线程的特点 1.线程的分类 java中的线程分为两类:守护线程和用户线程.唯一的区别是判断JVM何时离开. 守护线程是用来服务用户线程的,通过在start()方法前调用Thread.setDaem ...
- Java语法基础学习DaySixteen(多线程)
一.多线程的创建 1.作用 程序需要同时执行两个或多个任务时需要多线程. 程序需要实现需要等待的任务时,如用户输入.文件读写操作.网络操作.搜索等,需要多线程. 需要一些后台运行的程序时,需要多线程. ...
随机推荐
- 压缩图片 Image
图片压缩 class resizeImg: """缩略图""" def __init__(self,**args): self.args_k ...
- python IO 多路复用
一.epoll epoll 参考链接: https://www.cnblogs.com/Alanpy/articles/5125986.html epoll 参考链接: https://www.cn ...
- 网络请求(I)
NSURLSession 代理方法 有的时候,我们可能需要监听网络请求的过程(如下载文件需监听文件下载进度),那么就需要用到代理方法. #import "ViewController.h&q ...
- Oarcle 入门之where关键字
--where 关键字 --作用:过滤行 *将需要的行用where引导出来 用法: 1.判断符号:=,!=,<>,<,>,<=,>=,any,some,all; 例 ...
- Java内存模型学习笔记
Java内存模型(JMM):描述了java程序中各种变量(线程共享变量)的范根规则,以及在JVM中将变量存储到内存和从内存中读取出变量这样的底层细节.共享变量就是指一个线程中的变量在其他线程中也是可见 ...
- nodejs笔记之文件操作
文件操作包含: 读取文件 写入文件 删除文件 创建目录 删除目录 读取文件: // 异步操作 var fs = require("fs"); fs.readFile(". ...
- gets() 与 scanf() 的小尴尬
gets() 与 scanf() 函数相处呢有点小尴尬的,就是 gets() 在 scanf() 后边就爱捣乱.为什么呢,先了解它们两者之间的异同: 同: 都是可以接受连续的字符数据 并在字符结束后自 ...
- 浅谈Final
Java关键字final有“这是无法改变的”或者“终态的”含义,final可以修饰非抽象类.非抽象类成员方法和变量. final类不能被继承,没有子类,final类中的方法默认是final的.fina ...
- sigmod函数
#include <cmath> //math.h double sigmod(double x) { return 1/(1+exp(-x)); }
- js在线富文本插件的考虑
使用之前需要考虑的点: 1需要插件,是否需要很多的插件,还是说简单的那些功能就行了. 2界面考虑,看你喜欢那个界面了. 3图片是否需要上传图片服务器. 4文档如果为英文是否会影响开发. 5支持浏览器类 ...