Fork me on GitHub

一天一个Java基础——泛型

这学期的新课——设计模式,由我仰慕已久的老师传授,可惜思维过快,第一节就被老师挑中上去敲代码,自此在心里烙下了阴影,都是Java基础欠下的债

这学期的新课——算法设计与分析,虽老师不爱与同学互动式的讲课,但老师讲的挺好,不过由于数据结构欠缺课听的有点烧脑,都是数据结构欠下的债

这学期的新课——英语口语,虽外教老师风骚逗趣浪荡不羁爱自由,但我辈词汇量欠缺,表明淡定说yeah,但心中一万匹草泥马策马奔腾,都是英语欠下的债

 

1.泛型类

  实体类(容器类),经常重用的类,下面是一个没有用泛型的实体类:

 1 public class User{
 2     private String username;
 3     private int number;
 4     public String getUsername() {
 5         return username;
 6     }
 7     public void setUsername(String username) {
 8         this.username = username;
 9     }
10     public int getNumber() {
11         return number;
12     }
13     public void setNumber(int number) {
14         this.number = number;
15     }
16     public String toString() {
17         return "User [username=" + username + ", number=" + number + "]";
18     }
19     public User(String username, int number) {
20         super();
21         this.username = username;
22         this.number = number;
23     }
24     public User() {
25         super();
26     }
27 }

  属性number可以作为存放学生的证件号码,如果是int类型,11位的学号是够用了,但如果是身份证呢,一是长度不够,二是存在字符X,所以就需要重定义,那么这样这个实体类的重用性就很低了。

  但如果用上泛型,就是这样的:

 1 public class User<K,V> {
 2     private K usrename;
 3     private V number;
 4     public K getUsrename() {
 5         return usrename;
 6     }
 7     public void setUsrename(K usrename) {
 8         this.usrename = usrename;
 9     }
10     public V getNumber() {
11         return number;
12     }
13     public void setNumber(V number) {
14         this.number = number;
15     }
16     public String toString() {
17         return "User [usrename=" + usrename + ", number=" + number + "]";
18     }
19     public User(K usrename, V number) {
20         super();
21         this.usrename = usrename;
22         this.number = number;
23     }
24     public User() {
25         super();
26     }
27 }

  这样的好处就是:

 1 public class Test1 {
 2     public static void main(String[] args) {
 3         User<String,Integer> u = new User<String,Integer>();
 4         u.setUsrename("zhengbin");
 5         u.setNumber(2013734217);
 6         User<String,String> u1 = new User<String,String>();
 7         u1.setUsrename("zhengbin");
 8         u1.setNumber("4*****19951029****");
 9         System.out.println(u);
10         System.out.println(u1);
11     }
12 }

  运行结果:

User [usrename=zhengbin, number=2013734217]
User [usrename=zhengbin, number=41****19951029****]

  注意:

    (1) 按照惯例,像E或T这样的单个大写字母用于表示一个形式泛型类型

    (2) 泛型类型必须是引用类型。不能用像int、double或char这样的基本类型来替换泛型类型

    

2.泛型接口

   定义一个生成器的接口:

1 package Entity;
2 
3 public interface Generator<T> {
4     public T next();
5 }

  实现这个接口:

 1 package Test;
 2 import java.util.Random;
 3 import Entity.Generator;
 4 public class FruitGenerator implements Generator<String> {
 5     private String[] fruits = new String[]{"Apple", "Banana", "Pear"};
 6     public String next() {
 7         Random rand = new Random();
 8         return fruits[rand.nextInt(3)];
 9     }
10 }

  测试类:

 1 package Test;
 2 public class Main {
 3     public static void main(String[] args) {
 4         FruitGenerator generator = new FruitGenerator();
 5         System.out.println(generator.next());
 6         System.out.println(generator.next());
 7         System.out.println(generator.next());
 8         System.out.println(generator.next());
 9     }
10 }

  运行结果:

Banana
Apple
Apple
Pear

 

3.泛型方法

  从jdk 1.5开始,可以定义泛型接口,和泛型类,还可以使用泛型类型来定义泛型方法

 1 public class Test2 {
 2     public static void main(String[] args) {
 3         Integer[] integers = {1,2,3,4,5};
 4         String[] strings = {"London","Paris","New York","Austin"};
 5         //为了调用泛型方法,需要将实际类型放在尖括号内作为方法名的前缀(不加也行)
 6         Test2.<Integer>print(integers);
 7         Test2.<String>print(strings);
 8     }
 9     
10     public static <E> void print(E[] list){
11         for(int i = 0;i < list.length;i++){
12             System.out.print(list[i]+"-");
13         }
14         System.out.println();
15     }
16 }

  可以看到方法的参数彻底泛化了,这个过程涉及到编译器的类型推导和自动打包,也就说原来需要我们自己对类型进行的判断和处理,现在编译器帮我们做了

  这样在定义方法的时候不必考虑以后到底需要处理哪些类型的参数,大大增加了编程的灵活性

 

4.通配泛型

   通配泛型类型有三种形式:

  (1)? ,称为非受限通配,它和? extends Object 是一样的

  (2)? extends T 称为受限通配

  (3)? super T 称为下限通配,表示T或T的一个未知父类型

posted @ 2016-03-31 22:26  郑斌blog  阅读(597)  评论(0编辑  收藏  举报