java泛型学习笔记

来源:互联网 发布:手机照片转油画软件 编辑:程序博客网 时间:2024/05/21 21:40
经历了痛苦的期末考试以及十天的快活天堂之后,本人终于再次开始学习IT技术了。
这次我学习的是java。
学习基于《Java语言程序设计 进阶篇》

泛型(generic)是指参数化的能力。
可以定义带泛型类型的类或方法,随后编译器会用具体的类型来替换它。
使用泛型的主要优点是能够在编译时而不是在运行时检测出错误。

java1.5以后java.lang.Comparable接口的定义:
package java.lang;
public interface Comparable<T>{
    public int compareTo(T o);
}

<T>表示形式泛型类型(Format generic type),随后用实际具体类型(actual concrete type)来替换它。
替换泛型类型称为泛型实例化。

使用:
ArrayList<String> list=new ArrayList<String>();
list.add("aaa");
//如果向其中加入非字符串,会编译错误

注:
泛型类型必须是引用类型,不能用int,char,double之类,int用Integer代替之类……

定义泛型类和接口:
书上的例子:
public class GenericStack<E>{
    private java.util.ArrayList<E> list=new java.util.ArrayList<E>();

    public int getSize(){
        return list.size();
    }

    public E peek(){
        return list.get(getSize()-1);
    }

    public void push(E o){
        list.add(o);
    }

    public void pop(){
        E o=list.get(getSize()-1);
        list.remove(getSize()-1);
        return o;
    }

    public boolean isEmpty(){
        return list.isEmpty();
    }
}
//本人注释:上面是用ArrayList<E>实现的一个简单的通用栈
//使用:
GenericStack<String> stack1=new GenericStack<String>();
……

泛型方法:
public <E> E func(E o){
    return o;
}
使用:XX.<String>func(string);

原始类型有点危险,如两个Comparable比较,成了int和String比较,因此用向后兼容
public class Max1{
    public static <E extends Comparable<E>> E max(E o1,E o2){
        if(o1.compareTo(o2)>0){
            return o1;
        }
        else
            return o2;
    }
}
//上面代码如果Max.max("aa",2);这样的话会编译错误,因此安全了。

通配泛型
例:
如果有一个max(intStack),其中intStack是Integer类型的话,而调用的方法则是GenericStack(Number)的话,就会编译错误
解决方法:使用通配泛型
通配泛型类型有三种:
?    非受限通配(unbounded wildcard),它和? extends Object是一样的
? extends T     受限通配(bounded wildcard),表示T或T的一个未知子类型
? super T     下限通配(lower-bound wildcard),表示T或T的一个未知父类型
使用情况:
<?>,表示神马类型都行,因为这个等同于<? extends Object>,但是不能GenericStack<Object>替GenericStack<?>,因为这样和GenericStack<Number>不适用于GenericStack<Integer>一样道理,因为intStack不是GenericStack<Object>的实例。
至于<? extends T>限定了T或T的子类,而<? super T>限定了T或T的父类,这都很好理解,因此不废话了。

消除泛型
使用原始类型的话,编译时检不出来,只有运行错误,因此要使用泛型,这样编译时错误就能检出来,但是如果编译时没有检出错误,即么编译器会把泛型转为原始类型。
即是说原来的ArrayList<String> 变回ArrayList,会是get方法之类的会在前面加个(String),然后E之类的变成了Object之类
如果有
ArrayList<String> list1=new ArrayList<String>();
ArrayList<Integer> list2=new ArrayList<Integer>();
那么事实上list1和list2都是ArrayList的实例。

对泛型的限制:
1 不能使用new E()
2 不能使用new E[]
  但可以E[] e=(E[])new Object[xx];但会出一个无法避免的编译警告,因为编译器无法保证运行时类型转换成功
3 在静态环境下不允许类的参数是泛型类型
4 异常类不能是泛型的

0 0