首页 Linux Java高级特性之泛型的基本了解与使用

Java高级特性之泛型的基本了解与使用

为什么要使用泛型?
 
在Java中增加泛型之前,泛型程序设计是用继承来实现的,例如ArrayList,只维护Object引用的数组:
 
public class ArrayList{
  private Object[] elementData;
 
  public Object get(int i){…}
  public void add(Object o){…}       
}
 
在这里有一个问题,就是每次使用的时候,都必须进行一次强制类型转换
 
ArrayList list = new ArrayList();

String name = (String)list.get(0);
 
可以发现还没有错误检查,如果是其他类型会检测不到,当添加的时候,可以是任何类的对象
 
每次都转换一次很麻烦,用什么解决呢,类型参数!
 
ArrayList<String> list = new ArrayList<String>();
//在JAVASE 7以后的版本中,可以直接使用一下方法来声明了
ArrayList<String> list = new ArrayList<>();简单泛型类
 
public class Pair<T>{
  private T first;
  private T second;
 
  public Pair(){first = null; second = null;}
  public Pair(T first, T second){this.first = first; this.second = second}
 
  //get set
  …
 
}
 
现在,我们可以像现在这样定义了
 
Pair<String> test1 = new Pair<>();
Pair<Integer> test2 = new Pair<>();泛型方法
 
public class test{
  public static <T> T first(T…a){
  //…
  }
}
 
但是需要注意的是,下面这几种,并不是泛型方法,不要混淆
 
public class test<T>{
  private T t;
 
  //这个不是,只是一个普通的成员的方法
  public test(T t){
    this.t = t;
  }
  //这个也不是,只是泛型类是形参
  public void add(test<T> object){…}
}
 
通配符
 
通配符是什么,为什么要使用通配符?试想一下,如果我们在一个方法中要传入的参数可能是一个类的子类,这该怎么办呢?
 
public void test(Persion<Number> p){…}
 
x.test(Intger); //错误
x.test(Double);
 
不妨自己在编译器上试一试,这里是识别不了的,泛型中这两个没有关联关系,so,可以使用通配符
 
public void test(List<? extends T>){…}
 
这样子类和父类就联系起来了,?是类型实参,不是类型形参
 
ASP站长网如果像上面这样使用,我们可以add元素进去吗?反着思考一下,一个父类派生出很多个子类,我们在实例化的时候,很可能new出来的不是一个东西,这可不行呀,要存就得存一种,哪有Int,float都存进去的道理,如果还不明白可以看看代码
 
List<? extends Person> = new ArrayList<Student>();
List<? extends Person> = new ArrayList<Teacher>();
 
这样的话我们只能Get,并不能add,想要add那我们现在可以这样
 
public void test(List<? superT>){…}
 
如此之后,只能add,不能get,又是为什么呢,还是反着思考,既然我们能够add元素进去,但是每一个元素的实际类型不相同
 
List<? super Student> = new ArrayList<Student>();
List<? super Student> = new ArrayList<Person>();
 
当我们想get到Student的时候,可能是一个Person类型,这个Person可能是个Teacher
 
说了这么多,终于到了类型擦除

关于作者: dawei

【声明】:九江站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

热门文章