泛型平时用的最多的就是集合了,但是有时候看人家的代码,有自定义泛型方法,都忘了,所以再看看泛型,学习一下。
泛型2个作用:
1,安全:存数据的时候类型检查
2,省心:取数据的时候不用类型转换
例子程序:
package generic; import java.util.ArrayList; import java.util.List; /** * 1,泛型:标签,泛化类型 * 2,作用:安全 省心 * @author Administrator * */ public class Test01 { public static void main(String[] args) { /** * JDK1.5之后,泛型 */ List<String> list = new ArrayList<String>(); //安全,add的时候会类型检查 list.add("牛贝"); list.add("张三"); //list.add(100);//类型检查 //省心 String ele = list.get(0); System.out.println(ele); //jdk1.5之前 List list2 = new ArrayList(); list2.add(100); list2.add("大表哥"); //取出数据 Object obj = list2.get(0); Integer num = (Integer)obj; //麻烦 //不安全 num = (Integer)list2.get(1);// java.lang.ClassCastException if(list2.get(1) instanceof Integer){//需要手动类型转换 num = (Integer)list2.get(1);//才能保证安全 } } }
一,泛型类:
泛型字母:
需求:student类,成员变量 分数 javase,可以是整形:80分,小数型:85.5分,等级:“优秀”“差”,不用泛型就得用Object:
po类:
package generic; public class Student { /** * javase成绩 * 需求: * 成绩可能是 整数、小数、成绩等级如A、B、C * 所以写成Object */ private Object javase; public Student(){ } public Student(Object javase) { super(); this.javase = javase; } public Object getJavase() { return javase; } public void setJavase(Object javase) { this.javase = javase; } }
测试:
package generic; public class StudentApp { public static void main(String[] args) { Student stu = new Student(80);//存入整数 Object javase = stu.getJavase(); //类型检查 处理转换异常 if(javase instanceof Integer){ Integer score = (Integer)javase;//强制类型转换 } stu = new Student("优秀"); javase = stu.getJavase(); if(javase instanceof String){ String score = (String)javase; } } }
使用泛型类:
package generic; /** * 自定义泛型类: * 1,<> -->单个字母,尽可能见名知意 * 2,T Type * K V Key Value * E Element * 3,注意泛型不能使用在静态属性上 */ //T type ,类型 public class MyStudent<T> { private T javase; // private static T test;//静态编译错误 public MyStudent(){} public MyStudent(T javase) { super(); this.javase = javase; } public T getJavase() { return javase; } public void setJavase(T javase) { this.javase = javase; } }
测试:
package generic; public class MyStudentApp { public static void main(String[] args) { MyStudent<Integer> stu = new MyStudent<Integer>(); //安全:类型检查 stu.setJavase(80); //省心: Integer javase = stu.getJavase(); } }
二、泛型接口
package generic; /** * 泛型接口: * 泛型不能使用在全局常量上 * * @param <T> */ public interface Comparator<T> { //全局常量 /*public static final*/ int MAX_VALUE = 1024; //公共抽象方法 /*public abstract */T compare(T t); }
三、泛型方法
可以在非泛型类中定义,在返回类型前加 <字母>
package generic; import java.io.Closeable; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 非泛型类定义泛型方法 * 定义:在返回类型前加 <字母> * @author Administrator * */ public class Method { //泛型方法 public static <T> void test(T t){ System.out.println(t); } //泛型继承一个接口 public static <T extends List> void test(T t){ t.add("123"); t.add(456); System.out.println(t.get(0)); } /** * Closeable接口,有close()方法,释放资源 * @param a 可变参数,类似数组用法 */ public static <T extends Closeable> void test(T... a){ for (T temp : a) { if(temp != null){ try { temp.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void main(String[] args) throws FileNotFoundException { test("我是泛型方法"); List list = new ArrayList<>(); list.add("我是有继承泛型方法啊!"); test(list); test(new FileInputStream("a.txt")); } }
总结:
- 泛型概念:<T> 泛化类型
- 泛型作用:安全 省心
- 自定义泛型
a) 泛型类: ClassName<字母,...> T E K V 可以有多个泛型参数 注意:只能用在成员变量上 只能使用引用类型
b)泛型接口:InterfaceName<字母, ...>; 注意:只能用在抽象方法上
c)泛型方法:<字母 [extends 接口/类],...> 返回类型|void 方法名();