泛型(java菜鸟的课堂笔记)

1. 泛型的简单运 用和意义

2. 泛型的上限与下限

3. 泛型和 子类继承的限制

4. 泛型类和泛型 方法

5. 泛型嵌套和泛型擦除

泛型(Generic)

什 么是泛型:

?java5开始出现的 一种对Java语 言类型的 一种拓 展,以 支持创建可以按类型进 行 参数化的类.可以把类型参数看作是使 用参数类型时指定的类型占位符,就好 比 方法的形式参数是实际参数的占位符 一样.

?泛型能保证 大型应 用程序的类型安全和良好的维护性;使 用泛型的优势:

?类型安全,使编译器 对泛型定义的类型做判断限制.如保证TreeSet 里 的元素类型

必须 一致;

?消除强制类型的转换,如,使 用Comparable 比较时每次都需要类型强转;

泛型类

在类声明时通过 一个标识符表示类中某个字段的类型或者某个 方法的返回值或参数的类型,这样在类声明或实例 化的时候只要指定 自 己需要的类型就ok。

声明带泛型的类: class 类名<泛型类型1,泛型类型2……>{

泛型类型 变量 名;泛型类型  方法名(){}

返回值类型  方法名(泛型类型 变量 名){}

}

使 用带泛型的类:

类名<具体类> 对象名 = new 类名<具体类>();

注意:

类型参数规范:推荐使 用规范-常 见的泛型,泛型只保存在源 文件中,class 文件中不 存在;也就是说在编译阶段就会丢失,基本数据类型不 能作为泛型类型;

K 键, 比如映射的键 key的类型

V  值, 比如Map的值 value类型

E  元素, 比如Set<E>  Element表示元素,元素的类型

T 泛型,Type的意思

思考List<Object> l   和 List<String> l 是否可以运 行

通配符

在进 行 引 用传递的时候泛型类型必须匹配才可以传递,否则编译不 通过;使 用 ? ,表示未知类型的泛型对象:

?List<?> 表示未知元素的List集合;

?这种带通配符的List仅表示各种泛型List的 父类,并不 能把元素添加 入集合中;

?List<?> list = new ArrayList<>(); list.add(1);//ERROR 编译器  无法基于信息作类型推断

public void show(List<?> list){}

?//表示可接受任意类型的List集合

泛型的上限与下限

设置泛型对象的上限使 用extends,表示参数类型只能是该类型或该类型的 子类:

?声明对象:类名<? extends 类> 对象名

?定义类:类名<泛型标签 extends 类>{}

设置泛型对象的下限使 用super,表示参数类型只能是该类型或该类型的 父类:

?声明对象:类名<? super 类> 对象名称

?定义类:类名<泛型标签 extends类>{}

public static void  show(List<? extends Number> l){

}

public static void  show(List<? super String> l){

}

public static void main(String[] args) { Person<Integer> p1 = new Person<>(); p1.setVal(99);

Person<Double> p2 = new Person<>(); p2.setVal(3.14);

Person<String> p3 = new Person<>(); p3.setVal("007");

show(p1);//√ show(p2);//√ show(p3);//×

}

public static void show(Person<? extends Number> p){ System.out.println(p.getVal());

}

public static void main(String[] args) { Person<Integer> p1 = new Person<>(); p1.setVal(99);//Integer Person<Double> p2 = new Person<>(); p2.setVal(3.14);//Double

Person<String> p3 = new Person<>(); p3.setVal("007");//String Person<Object> p4 = new Person<>(); p4.setVal(new Object());//Object show(p1);//×

show(p2);//× show(p3);//√ show(p4);//√

}

public static void show(Person<? super String> p){ System.out.println(p.getVal());

}

泛型接 口

java5后,可以声明泛型接 口,声明 方式和声明泛型类是 一样的。

?public interface IDAO<T>{}

泛型接 口 子类有两种 方式:

?直接在 子类后申明泛型;

?在 子类实现的接 口中给出具体的泛型类型

public class DaoImpl<T> implements IDAO<T>{

}

public class DaoImpl implements IDAO<String> {

}

泛型 方法

方法中可定义泛型参数,形参的参数类型就是实参的类型。格式:

?<泛型标签> 返回值类型  方法名([泛型标签 参数]...)

public static <T> T show(T param){ return param;

}

.....main.....{ System.out.println(show(new Date())); System.out.println(show("cditcast"));

}

泛型使 用

通过泛型 方法返回泛型对象

?此时必须在 方法返回类型处明确给出具体类型统 一传 入的参数类型泛型数组

public <T> T[] show(T[] ts) {

}

public <T> void show(T ... ts){

}

泛型的嵌套

可以从 一个类的泛型中指向另 一个类的泛型:

public class Demo1 {

public static void main(String[] args) { Map<String,String> map = new HashMap<>(); map.put("1", "A");

map.put("2", "B"); map.put("3", "C"); map.put("4", "D");

Set<Map.Entry<String, String>> set = map.entrySet(); Iterator<Map.Entry<String, String>> it = set.iterator(); while(it.hasNext()) {

Map.Entry<String, String> entry = it.next(); System.out.println(entry.getKey() +"-->" + entry.getValue());

}

}

}

泛型的擦除

在严格的泛型代码 里 ,带泛型声明的类总应该带着类型参数。但是为了 和 老 的Java代码保持 一致,也允许在使 用带泛型声明的类时不 指定类型参数,若没有为这个泛型类指定类型参数则该类型参数被称做 一个原始类型,默认是该声明参数时指定的最上限类型;

当把 一个具有泛型信息的对象赋给另 一个没有泛型信息的变量 时,则所有在尖括号之间的类型信息都被扔掉。

? 比如List<String> 类型转换成List,则该List对集合元素的类型检查变成了 变量 的上限即Object。

泛型的擦除和转换

class Num<T extends Number>{

private T t;

public Num(T t) {

this.t= t;

}

。。。。 getter/setter。。。。

}

public class Demo{

public static void main(String[] args) {

Num<Integer> n= new Num<>(5);

Integer i= n.getT();

Num n2 = n;//会丢掉泛型信息

Number num= n2.getT();

//Integer i= n2.getT();

}

}

public class Demo{

public static void main(String[] args) {

List<Integer> li= new ArrayList<>();

li.add(1);

List<String> ls= null;

//ls= li;不能转换

List list= li;

ls= list;//不会报错,只有未经检查警告,此时l ist实际引用的是List<Integer>

System.out.println("-->" + ls.get(0));//企图当做String类型对象取出

}

}

时间: 2024-11-11 21:43:03

泛型(java菜鸟的课堂笔记)的相关文章

面向对象(java菜鸟的课堂笔记)

类:相同的东西放在一起 分为属性和动作: 把一组或多组事物相同的特性的描述==>类 属性和动作被称为成员: //声明类的属性信息 public class **{ String name: int age; char sex; } //声明类的动作信息(要在属性信息里面) public void eat(){ System.out.println("eating"); } public void study(){ System.out.println("study&qu

JAVA 韩老师课堂笔记-- 1-22讲

1. 抽象类和接口的区别: 抽象类是指不能被实例化的类,由abstract关键字修饰. 抽象方法是指没有方法体的方法,也就是一个空方法,是要被子类或扩展类来具体实现的方法. 接口是更抽象的抽象类,因为抽象类中允许存在非抽象方法(甚至可以一个抽象方法都没有),而接口中的所有方法均必须是抽象方法: 2. 集合框架(Linkedlist, Arraylist, HashSet, HashMap,): 优势:没有大小限制.

线程(java课堂笔记)

1.两种方式的差异 2.线程的生命周期 3.线程控制(线程的方法) 4.线程同步 5.线程同步锁 一. 两种方式的差异 A extends Thread :简单 不能再继承其他类了(Java单继承)同份资源不共享 B implements Runnable:( 推荐) )多个线程共享一个目标资源,适合多线程处理同一份资源. 该类还可以继承其他类,也可以实现其他接口. 二. 线程的生命周期 新建:当程序使用new创建一个线程后,该线程处于新建状态,此时他和其他java对象一样,仅仅由Java虚拟机

JAVA的面向对象编程--------课堂笔记

JAVA的面向对象编程--------课堂笔记 面向对象主要针对面向过程. 面向过程的基本单元是函数.   什么是对象:EVERYTHING IS OBJECT(万物皆对象)   所有的事物都有两个方面: 有什么(属性):用来描述对象. 能够做什么(方法):告诉外界对象有那些功能. 后者以前者为基础. 大的对象的属性也可以是一个对象.   为什么要使用面向对象: 首先,面向对象符合人类看待事物的一般规律. 对象的方法的实现细节是屏蔽的,只有对象方法的实现者了解细节. 方法的定义非常重要.方法有参

Android菜鸟的成长笔记(27)——SurfaceView的使用

前面有关自定义View中进行了绘图,但View的绘图机制存在如下缺陷: 1.View缺乏双缓冲机制. 2.当程序需要更新View上的图像时,程序必须重绘View上显示的整张图片. 3.新线程无法直接更新View组件. 由于View存在上面缺陷,所以在游戏开发中一般使用SurfaceView来进行绘制,SurfaceView一般会与SurfaceHolder结合使用,SurfaceHolder用于向与之关联的SurfaceView上绘图,调用SurfaceView的getHolder()方法即可获

Android菜鸟的成长笔记(27)——ViewPager的使用

ViewPager是Android 3.0以上可以使用的API. 一.ViewPager能干什么? 1.微信5.0中连带滑动用ViewPager可以轻松实现. 2.实现类似于新浪微博的导航引导界面. 3.实现其他导航或菜单. 二.ViewPager的使用 1.添加布局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_pa

python优缺点分析及python种类,编码-课堂笔记及课后总结

1.Python的缺点: 相较于其它类型的语言可能运行速度上会略差.C语言的运行性能速度上最好,因为C最接近计算机底层. 2.Python的优点: 1).大数据处理,有专门的功能模块,比较方便. 2).Linux自带Python,运用更广泛,更方便. 3).Python可做自动化处理,自动化运维. 4).python小数字池:-5-257,提高效率,节约内存空间 3.Python的种类: Cpython:使用C解释器来解释 扩展名:.pyc     C解释器-.pyc(字节码)-机器码-cpu

java String 类 基础笔记

字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s = "abc";//存放于字符串常量池,产生1个对象 String s1=new String("abc");//堆内存中new创建了一个String对象,产生2个对象 String类中的equals比较字符串中的内容. 常用方法: 一:获取 1.获取字符串中字符的个数(长度):length();方法. 2.根据位置获取字符:charAt(int index); 3.根据字符获取在字符串中

java/android 设计模式学习笔记(14)---外观模式

这篇博客来介绍外观模式(Facade Pattern),外观模式也称为门面模式,它在开发过程中运用频率非常高,尤其是第三方 SDK 基本很大概率都会使用外观模式.通过一个外观类使得整个子系统只有一个统一的高层的接口,这样能够降低用户的使用成本,也对用户屏蔽了很多实现细节.当然,在我们的开发过程中,外观模式也是我们封装 API 的常用手段,例如网络模块.ImageLoader 模块等.其实我们在开发过程中可能已经使用过很多次外观模式,只是没有从理论层面去了解它. 转载请注明出处:http://bl