JAVA之旅(二十一)——泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符
JAVA之旅(二十一)——泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符
不知不觉JAVA之旅已经写到21篇了,不得不感叹当初自己坚持要重学一遍JAVA的信念,中途也算是非常的痛苦吧,不过熬到现在,已经算是有点效果了,继续加油,估计三十来篇就能结束自己的JAVA之旅了,go,go!
一.泛型的概述
什么是泛型,我们可以用一个很典型的例子来说明
package com.lgl.hellojava;
import java.util.ArrayList;
import java.util.Iterator;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
/**
* 泛型
*/
ArrayList al = new ArrayList();
al.add("hello 1");
al.add("hello 02");
al.add("hello 0300");
al.add("hello 084");
//添加int
al.add(5);
Iterator iterator = al.iterator();
while (iterator.hasNext()) {
String s = (String) iterator.next();
// 打印长度
sop(s.length());
}
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
这里,我们用一个arraylist存储的数据有String也有int,输出的结果
不会发现,他报的就是类型的异常,我们要怎么去解决?这里就牵扯出泛型来了
- 泛型:JDK1.5版本之后出现的新特性,用于解决安全问题,是一个安全机制;
我们要怎么使用?
ArrayList<String> al = new ArrayList<String>();
我定义了一个容器,容器的参数是String类型,规范了数据类型,就不能存其他的数据了,安全性提高了!
- 好处:讲运行时期出现的问题转移到了编译时期,方便程序员解决问题,让运行时期问题减少,安全
二.泛型的使用
泛型的格式:通过<>来定义要操作的引用数据类型,在使用JAVA提供的对象时,什么时候写泛型呢,通常在集合框架中很常见,只要见到<>就是定义泛型!
其实<>就是用来接收类型的,当使用集合时,将集合中要存储的数据类型,作为参数,传递到<>一样 ,我们来个小例子
package com.lgl.hellojava;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
TreeSet<String> tr = new TreeSet<String>(new LenComp());
tr.add("hello 01");
tr.add("hello 012");
tr.add("hello 013");
tr.add("hello 014");
Iterator<String> iterator = tr.iterator();
while (iterator.hasNext()) {
String string = iterator.next();
sop(string);
}
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
// 比较器
class LenComp implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
String s1 = o1;
int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
if (num == 0) {
return o1.compareTo(o2);
}
return num;
}
}
你可以仔细的看看里面是怎么用泛型的,就是一些小技巧
三.泛型类
这是我们优化代码比较常见的一种方式,我们可以看这块代码
package com.lgl.hellojava;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
Tool t = new Tool();
t.setW(new Worker());
t.getW();
}
// 输出
public static void sop(Object obj) {
System.out.println(obj);
}
}
//操作工人的工具类
class Tool {
private Worker w;
public Worker getW() {
return w;
}
public void setW(Worker w) {
this.w = w;
}
}
class Worker {
}
这里,有一个工人的类,我们定义一个工具类去操作,对吧,这个逻辑就是这么的简单,但是你回发现,如果我在定义一个学生的类,就又得需要一个学生的工具类了,我们为什么不去合并这个工具类,抽调共有的方法呢?你会说可以用Object?
//操作工人的工具类
class Tool {
private Object obj;
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}
这样的话,你如果传递的话,还是要定义床底类型,不然会报类型异常的,我们泛型的用法
class Utils<T> {
private T t;
public T getT() {
return t;
}
public void setT(T t) {
this.t = t;
}
}
由你来指定传递进来的参数,这样就可以为所欲为了
- 什么时候定义泛型类
当类中要操作的引用数据类型不确定的时候,早起定义Object来完成扩展,现在定义泛型来完成扩展
四.泛型方法
泛型除了定义在类中,还是可以定义在方法上的,我们来看一下
package com.lgl.hellojava;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
Demo<String> d = new Demo<String>();
d.show("hh");
d.print("aa");
}
}
class Demo<T> {
public void show(T t) {
System.out.println("show:" + t);
}
public void print(T t) {
System.out.println("print:" + t);
}
}
泛型类定义的泛型,在整个类中有效,如果被方面使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
- 为了让不同的方法可以操作不同的类型,而且类型不确定,那么可以将泛型定义在方法上
仔细看
class Demo {
public <T> void show(T t) {
}
public <T>void print(T t){
}
}
这样就可以传递泛型参数了
五.静态泛型方法
这个倒不是什么大知识点,就是注意一下,泛型方法不能使用静态的,也可以说静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上,就可以了
class Demo<T> {
public <T> void show(T t) {
}
public <T> void print(T t) {
}
public static <T> void method(T t) {
}
}
要放在static后面哦!
六.泛型接口
你类和方法都有了,怎么能少得了接口呢?
package com.lgl.hellojava;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
InterImpl<Integer> i = new InterImpl<Integer>();
i.show(55);
}
}
class InterImpl<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println("show:" + t);
}
}
interface Inter<T> {
void show(T t);
}
结构也差不多,传参数就行,但是这种情况是不多见的
七.泛型限定
我们来玩玩泛型的高级用法,go
先从例子切入正题
package com.lgl.hellojava;
import java.util.ArrayList;
import java.util.Iterator;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("hello 01");
al.add("hello 02");
al.add("hello 03");
al.add("hello 04");
ArrayList<Integer> all = new ArrayList<Integer>();
all.add(9);
all.add(596);
all.add(98);
all.add(97);
printColl(all);
}
//内容不明确
public static void printColl(ArrayList<?> als) {
Iterator<?> iterator = als.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
问号是占位符,上面的逻辑就是我们有两个arrayList,但是我们需要公用一个方法,内容不明确,所以用问号占位,其实实现的方式还有很多种,还有一种需求使用不到?的,因为?是打印任何的数据,但是我只需要打印限定的几种类型,这个时候该怎么做?
package com.lgl.hellojava;
import java.util.ArrayList;
import java.util.Iterator;
//公共的 类 类名
public class HelloJJAVA {
public static void main(String[] args) {
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("zhangsan"));
al.add(new Person("lisi"));
al.add(new Person("wangwu"));
ArrayList<Student> al1 = new ArrayList<Student>();
al1.add(new Student("zhangsan -- 1"));
al1.add(new Student("lisi -- 2"));
al1.add(new Student("wangwu -- 3"));
// ArrayList
printColl(al1);
}
// 内容不明确
public static void printColl(ArrayList<? extends Person> als) {
Iterator<? extends Person> iterator = als.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next().getName());
}
}
}
class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Student extends Person {
public Student(String name) {
super(name);
}
}
这里,就能打印出学生和人类,而不打印其他类型的参数了,这就叫泛型限定
- ?叫通配符,也可以理解为占位符
- 泛型的限定 ? extends E:E类型和E的子类型。这叫上限
- ? super E:可以接受E类型和E的父类,这叫下限
下限我就不演示了,有机会的同学可以自己试试看,还是挺好玩的
好的,我们本篇文章就到这里OK了,下一篇聊聊Map吧,恩,下篇再见
欢迎加群:555974449
JAVA之旅(二十一)——泛型的概述以及使用,泛型类,泛型方法,静态泛型方法,泛型接口,泛型限定,通配符的更多相关文章
- JAVA之旅(十一)——RuntimeException,异常的总结,Package,jar包,多线程概述
JAVA之旅(十一)--RuntimeException,异常的总结,Package,jar包,多程序概述 继续JAVA之旅 一.RuntimeException 在Exception种有一个特殊的子 ...
- JAVA之旅(三)——数组,堆栈内存结构,静态初始化,遍历,最值,选择/冒泡排序,二维数组,面向对象思想
JAVA之旅(三)--数组,堆栈内存结构,静态初始化,遍历,最值,选择/冒泡排序,二维数组,面向对象思想 我们继续JAVA之旅 一.数组 1.概念 数组就是同一种类型数据的集合,就是一个容器 数组的好 ...
- Java设计模式(二十一):职责链模式
职责链模式(Chain Of Responsibility Pattern) 职责链模式(Chain Of Responsibility Pattern):属于对象的行为模式.使多个对象都有机会处理请 ...
- 夯实Java基础(二十一)——Java反射机制
1.反射机制概述 Java反射机制是指程序在运行状态中,对于任何一个类,我们都能够知道这个类的所有属性和方法(包括private.protected等).对于任何一个对象,我们都能够对它的属性和方法进 ...
- Java笔记(二十一) 动态代理
动态代理 一.静态代理 代理的背后一般至少有一个实际对象,代理的外部功能和实际对象一般是一样的, 用户与代理打交道,不直接接触实际对象.代理存在的价值: 1)节省成本比较高的实际对象创建开销,按需延迟 ...
- Java并发(二十一):线程池实现原理
一.总览 线程池类ThreadPoolExecutor的相关类需要先了解: (图片来自:https://javadoop.com/post/java-thread-pool#%E6%80%BB%E8% ...
- Java从零开始学二十一(集合List接口)
一.List接口 List是Collection的子接口,里面可以保存各个重复的内容,此接口的定义如下: public interface List<E> extends Collecti ...
- Java学习笔记二十一:Java面向对象的三大特性之继承
Java面向对象的三大特性之继承 一:继承的概念: 继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类. 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的实例域和方 ...
- Java基础(二十一)集合(3)List集合
一.List接口 List集合为列表类型,列表的主要特征是以线性方式存储对象. 1.实例化List集合 List接口的常用实现类有ArrayList和LinkedList,根据实际需要可以使用两种方式 ...
- Java进阶专题(二十一) 消息中间件架构体系(3)-- Kafka研究
前言 Kafka 是一款分布式消息发布和订阅系统,具有高性能.高吞吐量的特点而被广泛应用与大数据传输场景.它是由 LinkedIn 公司开发,使用 Scala 语言编写,之后成为 Apache 基金会 ...
随机推荐
- 一个蒟蒻对FFT的理解(蒟蒻也能看懂的FFT)
建议同学们先自学一下"复数(虚数)"的性质.运算等知识,不然看这篇文章有很大概率看不懂. 前言 作为一个典型的蒟蒻,别人的博客都看不懂,只好自己写一篇了. 膜拜机房大佬 HY 一. ...
- python学习之路web框架
WEB框架的本质 python的WEB框架分为两大类: 1.自己写socket,自己处理请求 2.基于wsgi(Web Server Gateway Interface WEB服务网关接口),自己处理 ...
- oh forever love~
npm install -g forever forever start c9sdk/server.js --listen 0.0.0.0 --port 80 -a aa:111 -w ~ To el ...
- 微信自定义菜单url默认80端口问题解决
微信自定义菜单url默认80端口的,但是有些服务器上可能配置了多个tomcat.或者是刚好你服务器上80端口被占用了.在这样的情况下,我们可以通过如下方式解决: 首先安装apache,关于apache ...
- Swift:一个简单的货币转换器App在iOS10中的分析和完善
这本不算是一个完整的货币转换App,只不过是一个小巧的学习性质的程序.该App覆盖了如下几个知识点: 多国语言的支持 通过网络Api接口读取数据 最后我们来修复一个原来代码中的一个小错误作为完美的收尾 ...
- 在做自动化测试之前你需要知道的,转自:http://www.cnblogs.com/fnng/p/3653793.html
什么是自动化测? 做测试好几年了,真正学习和实践自动化测试一年,自我感觉这一个年中收获许多.一直想动笔写一篇文章分享自动化测试实践中的一些经验.终于决定花点时间来做这件事儿. 首先理清自动化测试的概念 ...
- github pages + Hexo + 域名绑定搭建个人博客增强版
概述 前面我们用github pages + Hexo 搭建了一个简单版的个人博客系统,但是里面的内容单调,很多功能不够完善,所以我们需要对yelle 的主题进行优化和完善.基本搭建请访问:http: ...
- 28 自定义View流式布局
流式布局每行的行高以本行中最高的元素作为高,如果一个元素放不下到一行时直接到第二行 FlowLayoutView package com.qf.sxy.customview05.widget; imp ...
- SSH 之 Spring的源码(二)——Bean实例化
首先来看一段代码,看过上一节的朋友肯定对这段代码并不陌生.这一段代码诠释了Spring加载bean的完整过程,包括读取配置文件,扫描包,加载类,实例化bean,注入bean属性依赖. <span ...
- Dynamics CRM2013 Odata的filter中含有日期字段时遇到的一个奇葩问题
在使用Odata拼写filter时我们一般都用工具,因为手写是件极不靠谱且错误率极高的事,下图是我用query designer拼出来的一个filter,因为时间是参数,所以在拷贝出下面这段filte ...