Java中Generics泛型

1. Java中Generics泛型 Generics泛型是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。 泛型的本质是参数化类型,也就是说...
1. Java中Generics泛型
Generics泛型是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。

泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。

import java.util.ArrayList;
import java.util.List;
public class ArrayListTest{
    public static void main(String[] args){
        List list = new ArrayList();
        list.add("string");
        list.add(new Integer(2));
        list.add(new Boolean(false));
        String str = (String)list.get(0);
        Integer in = (Integer)list.get(1);
        String b = (String)list.get(2);
    }
}
运行结果:
Exception in thread "main" java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String
    at org07.ArrayListTest.main(ArrayListTest.java:18)


2. 自定义泛型
自定义泛型,可以定义多个泛型Generic<T1, T2>,用set和get方法实现。
public class Generic<T1, T2>{
    private T1 foo1;
    private T2 foo2;
    public T1 getFoo1(){
        return foo1;
    }
    public void setFoo1(T1 foo1){
        this.foo1 = foo1;
    }
    public T2 getFoo2(){
        return foo2;
    }
    public void setFoo2(T2 foo2){
        this.foo2 = foo2;
    }
    public static void main(String[] args){
        Generic<Integer, Boolean> foo = new Generic<Integer, Boolean>();
        foo.setFoo1(new Integer(-20));
        foo.setFoo2(new Boolean(false));
        System.out.println(foo.getFoo1());
        System.out.println(foo.getFoo2());
    }
}
运行结果:
-20
false

泛型数组的存取
public class Generic2<T>{
    private T[] fooArray;
    public T[] getFooArray(){
        return fooArray;
    }
    public void setFooArray(T[] fooArray){
        this.fooArray = fooArray;
    }
    public static void main(String[] args){
        Generic2<String> foo = new Generic2<String>();
        String[] str1 = {"hello", "world", "welcome"};
        String[] str2 = null;
        foo.setFooArray(str1);
        str2 = foo.getFooArray();
        for(int i = 0; i < str2.length; i++){
            System.out.println(str2[i]);
        }
    }
}
运行结果:
hello
world
welcome


3. 泛型的泛型
public class WrapperFoo<T>{
    private GenericFoo3<T> foo;
    public GenericFoo3<T> getFoo(){
        return foo;
    }
    public void setFoo(GenericFoo3<T> foo){
        this.foo = foo;
    }
    public static void main(String[] args){
        GenericFoo3<Integer> foo = new GenericFoo3<Integer>();
        foo.setFoo(new Integer(-10));
        WrapperFoo<Integer> wrapper = new WrapperFoo<Integer>();
        wrapper.setFoo(foo);
        GenericFoo3<Integer> g = wrapper.getFoo();
        System.out.println(g.getFoo());
    }
}
class GenericFoo3<T>{
    private T foo;
    public T getFoo(){
        return foo;
    }
    public void setFoo(T foo){
        this.foo = foo;
    }
}
运行结果:
-10


4. 泛型上下边界
限制泛型的类型用extends关键字。ListGenericFoo<T extends List>
当我们没有指定泛型的类型或接口时,默认使用T extends Object,任何类型都可以作为参数传入。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class ListGenericFoo<T extends List>{
    private T[] fooArray;
    public T[] getFooArray(){
        return fooArray;
    }
    public void setFooArray(T[] fooArray){
        this.fooArray = fooArray;
    }
    public static void main(String[] args){
        ListGenericFoo<LinkedList> foo1 = new ListGenericFoo<LinkedList>();
        ListGenericFoo<ArrayList> foo2 = new ListGenericFoo<ArrayList>();
        LinkedList[] linkedList = new LinkedList[10];
        foo1.setFooArray(linkedList);
        ArrayList[] arrayList = new ArrayList[10];
        foo2.setFooArray(arrayList);
        // ListGenericFoo<HashMap> foo3 = new ListGenericFoo<HashMap>();
    }
}

GenericTest<? extends List> 在声明引用的时候才对泛型进行限定。
GenericTest<? super List> 在声明引用的时候才对泛型进行限定。(在List之上的泛型)
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class GenericTest<T>{
    private T foo;
    public T getFoo(){
        return foo;
    }
    public void setFoo(T foo){
        this.foo = foo;
    }
    public static void main(String[] args){
        GenericTest<? extends List> ge = null;
        ge = new GenericTest<ArrayList>();
        ge = new GenericTest<LinkedList>();
        // ge = new GenericTest<HashMap>();
        GenericTest<? super List> ge2 = null;
        ge2 = new GenericTest<Object>();
        GenericTest<String> ge3 = new GenericTest<String>();
        ge3.setFoo("hello world");
        GenericTest<?> ge4 = ge3;
        System.out.println(ge4.getFoo());
        ge4.setFoo(null);
        System.out.println(ge4.getFoo());
        // ge4.setFoo("welcome");
    }
}
运行结果:
hello world
null

ge4.setFoo("welcome");是错误的。因为需要强制类型转换。不符合泛型定义。
使用<?>或是<? extends SomeClass>的声明方式,意味著您只能通过该名称來取得所参考实例的信息,或者是移除某些信息,但不能增加它的信息,因为只知道当中放置的是SomeClass的子类,但不确定是什么类的实例,编译器不让您加入信息,理由是,如果可以加入信息的話,那么您就得記得取回的实例是什么类型,然后转换为原來的类型方可进行操作,这就失去了使用泛型的意义。

原文出处:http://andrew7676.iteye.com/blog/2432145

  • 发表于 2018-10-15 10:19
  • 阅读 ( 351 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除