java中的泛型

http://www.cnblogs.com/lzq198754/p/5780426.html      http://www.cnblogs.com/lwbqqyumidi/p/3837629.html

1.java中的泛型,为什么会出现泛型? (参数化类型,泛型一般在集合中会被经常用到)

//没有使用泛型
public
class FanxingTest { public static void main(String[] args){ List tempList = new ArrayList(); tempList.add("abcde"); tempList.add(100); for(int i=0;i<tempList.size();i++){ String tempStr = (String)tempList.get(i); //此处需要强制类型转换 } } }

以上如果没有使用泛型,程序中会需要出现强制类型转换。而且不小心放入一个Integer类型的值,会出现java.lang.ClassCastException(强制类型转换错误)异常。

//使用泛型
public
class FanxingTest { public static void main(String[] args){ List<String> tempList = new ArrayList<String>(); tempList.add("abcde"); //tempList.add(100); for(int i=0;i<tempList.size();i++){ String tempStr = tempList.get(i); } } }

以上使用了泛型<String>将这个List规范成只有String类型,只有String类型的值才能被放入到这个List里边,当执行tempList.add(100);时会出现一个编译错误,所以在这样可以保证在运行时不会出现ClassCastException异常。所以使用泛型可以保证程序的质量,减少程序出现运行时错误。

2.泛型只在程序编译是起作用,在程序运行时会将泛型擦除:

public class FanxingTest {
    public static void main(String[] args){
        List<String> tempList1 = new ArrayList<String>();     //String类型
        List<Integer> tempList2 = new ArrayList<Integer>();   //Integer类型
        System.out.println(tempList1.getClass().getName());
        System.out.println(tempList2.getClass().getName());
        System.out.println(tempList1.getClass().getName() == tempList2.getClass().getName());
    }
}
//输出结果
java.util.ArrayList
java.util.ArrayList
true

有以上代码可以看出,List的泛型在代码运行时是没有起作用的,输出两个不同泛型的类型是一样的,都是java.util.ArrayList。所以说泛型只在代码编译的时候存在,在运行时被擦除。

通过java反射机制的原理也可以证明:

public class FanxingTest {
    public static void main(String[] args){
        List<String> tempList = new ArrayList<String>();
        tempList.add("abcde");
        Class c = tempList.getClass();   //获取tempList对象的类型c
        try {
            Method method = c.getMethod("add", Object.class);  //给这个类c添加一个方法
            method.invoke(tempList, 100);   //在tempList这个对象上调用这个方法
            System.out.println(tempList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//输出结果
[abcde, 100]

以上通过反射机制实现,绕过了编译阶段也就绕过了泛型,虽然tempList是String类型的List,但是通过反射机制还是可以将integer类型的值放进去,而且没有报错,所以再一次证明泛型是在编译时有效,在运行时无效。

3.泛型不可以是基本数据类型的

因为当不加泛型的时候,默认是Object类型的,是类类型的,所以泛型不能够是基本数据类型的。

List<int> tempLiat = new ArrayList<int>();  //是会报错的,不能够这样写

4.泛型接口,泛型类和泛型方法(都可以自己定义)

//自定义泛型类和泛型方法
public class FanxingTest<T> {
    private T obj;
    public FanxingTest(T tempObj){
        this.obj = tempObj;
    }
    public T getObj() {
        return obj;
    }
    public void setObj(T obj) {
        this.obj = obj;
    }

    public void getData(FanxingTest<Number> fff){
        System.out.println(fff);
    }
    public static void main(String[] args){
        FanxingTest<Number> temp1 = new FanxingTest<Number>(100);
        Number str = temp1.getObj();
        FanxingTest<Integer> temp2 = new FanxingTest<Integer>(200);
        Integer num = temp2.getObj();
        
        temp1.getData(temp1);
        
        //temp2.getData(temp2);  //会报编译时错误
    }
}

以上是自定义的泛型类和泛型方法,在main方法中分别使用泛型创建了两个对象temp1和temp2,虽然Number是Integer的父类,但是当temp2.getData(temp2)时会报编译时错误。在泛型中只能使用定义好的类型。所以在泛型的理念中:在逻辑上FanxingTest<Number>不能视为FanxingTest<Integre>的父类。

5.这是通配符就应用而生(格式类似:FanxingTest<?>)

//自定义泛型类和泛型方法
public class FanxingTest<T> {
    private T obj;
    public FanxingTest(T tempObj){
        this.obj = tempObj;
    }
    public T getObj() {
        return obj;
    }
    public void setObj(T obj) {
        this.obj = obj;
    }

    public void getData(FanxingTest<?> fff){
        System.out.println(fff);
    }
    public static void main(String[] args){
        FanxingTest<Number> temp1 = new FanxingTest<Number>(100);
        Number str = temp1.getObj();
        FanxingTest<Integer> temp2 = new FanxingTest<Integer>(200);
        Integer num = temp2.getObj();
        
        temp1.getData(temp1);
      temp2.getData(temp2);
} }

运用了通配符之后,temp2.getData(temp2);就不会报错了。

类型通配符一般是使用 ? 代替具体的类型实参。注意了,此处是类型实参,而不是类型形参!且Box<?>在逻辑上是Box<Integer>、Box<Number>...等所有Box<具体类型实参>的父类。由此,我们依然可以定义泛型方法,来完成此类需求。

还有通配符上限 FanxingTest<? extends Number>

还有通配符下限 FanxingTest<? super Integer>

6.注意:Java中没有所谓的泛型数组一说。

原文地址:https://www.cnblogs.com/yuxin-555xt/p/6528216.html