首页 > 技术文章 > java泛型

lihaoyang 2017-07-01 22:31 原文

泛型平时用的最多的就是集合了,但是有时候看人家的代码,有自定义泛型方法,都忘了,所以再看看泛型,学习一下。

 

泛型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"));
    }
}

总结:

  1. 泛型概念:<T> 泛化类型
  2. 泛型作用:安全 省心
  3. 自定义泛型   

    a) 泛型类: ClassName<字母,...> T E K V  可以有多个泛型参数 注意:只能用在成员变量上 只能使用引用类型

    b)泛型接口:InterfaceName<字母, ...>;   注意:只能用在抽象方法上

    c)泛型方法:<字母 [extends  接口/类],...> 返回类型|void  方法名();

 

欢迎关注个人公众号一起交流学习:

推荐阅读