JAVA泛型详解 --- 学习笔记
来源:互联网 发布:问道1.52服务端源码 编辑:程序博客网 时间:2024/06/15 21:29
原文请戳此处!!!
1. 普通泛型
class Point<T>{ //此处可以随便写标识符号,T只是Type的简称 private T var; // var的类型由T指定,也就是:由外部指定 public T getVar(){ //返回值得类型也是由外部决定的 return var; } public void setVar(T var){ //设置的类型也由外部决定 this.var = var; }}public class GenericsDemo01{ public static void main(String args[]){ Point<String> p = new Point<String>(); //此处决定了类Point<T>里面的var类型为String类型 p.setVar("forfan06"); //设置字符串 System.out.println(p.getVar().length()); //此处分两步,一是取得字符串;二是获得字符串长度 }}
-----------------------------------------------------------------------------------------------------------
class Notepad<K, V>{ //指定了两个泛型类型T和V,当然,此处的T和V可以换成其他字符。但是为了方便识别,一般取一个有意义单词的大写首字母 private K key; // 此处的T和V均是由外部决定的 private V value; public K getKey(){ return this.key; } public V getValue(){ return this.value; } public void setKey(K key){ this.key = key; } public void setValue(V value){ this.value = value; }}public class GenericsDemo02{ public static void main(String args[]){ Notepad<String, Integer> t = null; //定义了两个泛型类型的对象。 t = new Notepad<String, Integer>(); //里面的key和value分别为String和Integer类型。 t.setKey("饭饭"); //设置对象t的内容 t.setValue(20); System.out.print("姓名:" + t.getKey()); //获取对象t的属性 System.out.println(", 年龄:" + t.getValue()); }}
2. 通配符
class Info<T>{ private T var; //定义泛型变量,由外部决定 public void setVar(T var){ this.var = var; } public T getVar(){ return this.var; } public String toString(){ //直接打印 return this.var.toString(); }}public class GenericsDemo03{ public static void main(String args[]){ Info<String> i = new Info<String>(); //使用String类型为泛型类型 i.setVar("forfan06"); fun(i); } public static void fun(Info<?> info){ //此处Info<?>里面没有明确指明泛型类型,说明可以接受任意的泛型对象。 System.out.println("内容是:" + info); }}
更好的验证通配符的作用:增加Info<Integer>如下代码:也可以正常运行!!!
class Info<T>{ private T var; //定义泛型变量,由外部决定 public void setVar(T var){ this.var = var; } public T getVar(){ return this.var; } public String toString(){ //直接打印 return this.var.toString(); }}public class GenericsDemo03{ public static void main(String args[]){ Info<String> i = new Info<String>(); //使用String类型为泛型类型 i.setVar("forfan06"); fun(i); Info<Integer> s = new Info<Integer>(); s.setVar(28); fun(s); } public static void fun(Info<?> info){ //此处Info<?>里面没有明确指明泛型类型,说明可以接受任意的泛型对象。 System.out.println("内容是:" + info); }}
上面程序若修改为:
class Info<T>{ private T var; //定义泛型变量,由外部决定 public void setVar(T var){ this.var = var; } public T getVar(){ return this.var; } public String toString(){ //直接打印 return this.var.toString(); }}public class GenericsDemo03{ public static void main(String args[]){ Info<String> i = new Info<String>(); //使用String类型为泛型类型 i.setVar("forfan06"); fun(i); Info<Integer> s = new Info<Integer>(); s.setVar(28); fun(s); } public static void fun(Info<T> info){ //此处Info<?>里面没有明确指明泛型类型,说明可以接受任意的泛型对象。 System.out.println("内容是:" + info); }}
则会出现编译错误!!!!!!!!!!!!
GenericsDemo03.java:22: error: cannot find symbol public static void fun(Info info){ ^ symbol: class T location: class GenericsDemo031 error编译错误
3. 受限泛型
上限:
class Info<T>{ private T var; public void setVar(T var){ this.var = var; } public T getVar(){ return this.var; } public String toString(){ return this.var.toString(); }}public class GenericsDemo04{ public static void main(String args[]){ Info<Integer> i1 = new Info<Integer>(); //声明Integer类的泛型对象 Info<Float> i2 = new Info<Float>(); //声明Float类的泛型对象 i1.setVar(27); //设置整数(小数), 自动装箱!! i2.setVar(10.53f); fun(i1); fun(i2); } public static void fun(Info<? extends Number> temp){ //只能接受Number类及其子类的实例!!!! System.out.print(temp + "、"); }}
下限:
class Info<T>{ private T var; public void setVar(T var){ this.var = var; } public T getVar(){ return this.var; } public String toString(){ return this.var.toString(); }}public class GenericsDemo04{ public static void main(String args[]){ Info<String> i1 = new Info<String>(); Info<Object> i2 = new Info<Object>(); i1.setVar("forfan06"); i2.setVar(new Object()); fun(i1); fun(i2); } public static void fun(Info<? super String> temp){ //只能接收String类或其父类(Object类)类型的泛型 System.out.print(temp + "、"); }}
4. 泛型无法向上转型
class Info<T>{ private T var; public void setVar(T var){ this.var = var; } public T getVar(){ return this.var; } public String toString(){ return this.var.toString(); }}public class GenericsDemo05{ public static void main(String args[]){ Info<String> i1 = new Info<String>(); Info<Object> i2 = null; i2 = i1; //此句会出错:error: incompatible types }}
运行得到错误:
GenericsDemo05.java:17: error: incompatible types i2 = i1; //此句会出错:incompatible types ^ required: Info found: Info1 error编译错误
- 此时Info<String> i1, Info<Object> i2中,i2已经不是i1的基类了!!!所以不存在向上转型这一说法!!!!!
5. 泛型接口
interface Info<T>{ //在接口中定义泛型 public T getVar(); //定义抽象方法,抽象方法的返回值就是泛型类型}class InfoImpl<T> implements Info<T>{ //定义泛型接口的子类 private T var; public InfoImpl(T var){ //通过构造方法设置属性内容 this.var = var; } public T getVar(){ return this.var; } public void setVar(T var){ this.var = var; }}public class GenericsDemo06{ public static void main(String args[]){ Info<String> i = null; //声明接口对象,泛型T此时为String类型 i = new InfoImpl<String>("forfan06"); //通过子类实例化对象 System.out.println("内容:" + i.getVar()); }}
interface Info<T>{ //在接口中定义泛型 public T getVar(); //定义抽象方法,抽象方法的返回值就是泛型类型}class InfoImpl implements Info<String>{ //定义泛型接口的子类 private String var; public InfoImpl(String var){ //通过构造方法设置属性内容 this.var = var; } public String getVar(){ return this.var; } public void setVar(String var){ this.var = var; }}public class GenericsDemo06{ public static void main(String args[]){ Info i = null; //声明接口对象 i = new InfoImpl("forfan06"); //通过子类实例化对象 System.out.println("内容:" + i.getVar()); }}
6. 泛型方法
声明格式:
[访问权限] <泛型标识> 泛型标识 方法名称([泛型标识 参数名称])
class Demo{ public <T> T fun(T t){ //可以接收任意类型的数据 return t; //直接把参数返回 }}public class GenericsDemo07{ public static void main(String args[]){ Demo d= new Demo(); String str = d.fun("forfan06"); int i = d.fun(28); //传递数字,自动装箱 System.out.println(str); System.out.println(i); }}
7. 通过泛型方法返回泛型类型实例
class Info<T extends Number>{ //指定上限,只能是数字类型。(只能是Number类的子类) private T var; public T getVar(){ return this.var; } public void setVar(T var){ this.var = var; } public String toString(){ //覆写Object类中的toString()方法 return this.var.toString(); }}public class GenericsDemo08{ public static void main(String args[]){ Info<Integer> i = fun(30); System.out.println(i.getVar()); } public static <T extends Number> Info<T> fun(T param){ //方法中传入或返回的泛型类型由调用方法时所设置的参数类型决定 Info<T> temp = new Info<T>(); //根据传入的数据类型实例化Info temp.setVar(param); //将传递的内容设置到Info对象的var属性中 return temp; //返回实例化对象 }}
8. 使用泛型统一传入的参数类型
class Info<T>{ private T var; public T getVar(){ return this.var; } public void setVar(T var){ this.var = var; } public String toString(){ return this.var.toString(); }}public class GenericsDemo09{ public static void main(String args[]){ Info<String> i1 = new Info<String>(); Info<String> i2 = new Info<String>(); i1.setVar("forfan06"); i2.setVar("你好!"); add(i1,i2); } public static <T> void add(Info<T> i1, Info<T> i2){ System.out.println(i1.getVar() + " " + i2.getVar()); }}
9. 泛型数组
public class GenericsDemo10{ public static void main(String args[]){ Integer i[] = fun1(1, 2, 3, 4, 5, 6); //返回泛型数组 fun2(i); } public static <T> T[] fun1(T...arg){ //接收可变参数 return arg; //返回泛型数组 } public static <T> void fun2(T param[]){ //输出 System.out.println("接收泛型数组:"); for(T t:param){ System.out.print(t + "、"); } }}
此时运行会得到以下警告:
GenericsDemo10.java uses unchecked or unsafe operations.Note: Recompile with -Xlint:unchecked for details.
出现上面警告是因为用到了JAVA5.0的泛型,而5.0的泛型不做类型检查,例如ArrayList = a new ArrayList(); a.add("hello");这样会出现警告!解决方法有以下几种:
- 在方法的前面加上@SuppressWarnings("unchecked")
- 声明泛型类型,例如ArrayList<Object> a = new ArrayList<Object>();
- 使用1.4兼容JDK来编译, javac -source 1.4 Test.java
- 也可以查看警告信息,javac Xlint:unchecked Test.java。这样会显示详细的警告信息。
10. 泛型的嵌套设置
class Info<T, V>{ private T var; private V value; public Info(T var, V value){ this.setVar(var); this.setValue(value); } public void setVar(T var){ this.var = var; } public void setValue(V value){ this.value = value; } public T getVar(){ return this.var; } public V getValue(){ return this.value; }}class Demo<S>{ private S info; public Demo(S info){ this.setInfo(info); } public void setInfo(S info){ this.info = info; } public S getInfo(){ return this.info; }}public class GenericsDemo11{ public static void main(String args[]){ Demo<Info<String, Integer>> d = null; //将Info作为Demo的泛型类型 Info<String, Integer> i = null; //Info指定两个泛型类型 i = new Info<String, Integer>("forfan06", 30); //实例化Info对象 d = new Demo<Info<String, Integer>>(i); //在Demo类中设置Info类的对象 System.out.println("内容一:" + d.getInfo().getVar()); System.out.println("内容二:" + d.getInfo().getValue()); }}
泛型方法不一定要通过参数来确定泛型准确类型,可以只通过返回值,比如:
public static <E> ArrayList<E> new ArrayList(){ return new ArrayList<E>();}public List<PrepaidHistory> queryHistories(Long skyid, PrepaidHistoryType type, Date from, Date end){ ... return Lists.newArrayList();}
这样Lists.newArrayList();
智能的知道返回类型为PrepaidHistory
0 0
- JAVA泛型详解 --- 学习笔记
- 疯狂Java学习笔记(47)-----------泛型详解
- 疯狂Java学习笔记(48)------------泛型详解
- java基础学习笔记——泛型代码详解
- Java学习笔记(47)-----------泛型详解
- Java学习笔记(48)------------泛型详解
- Java泛型学习笔记
- java泛型学习笔记
- java泛型学习笔记
- java泛型学习笔记
- java 泛型学习笔记
- java 泛型学习笔记
- Java泛型学习笔记
- Java泛型学习笔记
- java泛型学习笔记
- Java泛型学习笔记
- Java泛型学习笔记
- Java学习笔记泛型
- jdk1.7 win64 下载及安装
- flash
- ios代码0727分析题解析
- Android的学习之路(一)开发环境的搭建
- 全面掌握Java的异常处理机制
- JAVA泛型详解 --- 学习笔记
- 基础—对两个整数变量的值进行互换(不用第三个变量)
- 矩阵PKU3233二分加矩阵快速幂
- Evolutionary Database design
- maxent:最大熵模型的java实现,GIS训练
- C++内存分配相关
- 导入带隐藏列的Excel发生错位
- iOS开发-学习资料视频
- 学习知识的感悟