黑马程序员技术交流社区

标题: 一个关于泛型的问题 [打印本页]

作者: 乔钰博    时间: 2014-3-20 16:56
标题: 一个关于泛型的问题
本帖最后由 乔钰博 于 2014-3-21 11:05 编辑
  1. public class Point<T> {

  2.         private T var;

  3.         public T getVar() {
  4.                 return var;
  5.         }

  6.         public void setVar(T var) {
  7.                 this.var = var;
  8.         }
  9.         
  10.         public static void main(String[] args) {
  11.                 Point<?> p = new Point<String>();
  12.                 p.setVar(null);
  13.                 p.setVar("abc");//编译会报错
  14.         }
  15. }
复制代码

我想问下如果使用Point<?>,就不能设置被泛型指定的内容,但是为什么p.setVar(null)就可以呢?
还有Point<?>这种形式不能使用方法,那作用是什么?
作者: 上官睿鹏    时间: 2014-3-21 10:53
null  对任何引用类型而言都是一个空值,但当你传递“abc”代表对象是一个String类型,而Point<?>
因为在不知道该 Point实例的类型参数 T 的情况下它不能检验这个操作的安全性。由于 Point是一个 Point<?> 而不是一个原始的 Point,编译器知道存在一些 T 充当 Point的类型参数,但由于不知道 T 具体是什么,您不能调用 setVar() 因为不能检验这么做不会违反 Point的类型安全限制
你直接Point<String> p = new Point<String>();就行了
作者: papercup    时间: 2014-3-21 11:19
为了解决类型被限制死了不能动态根据实例来确定的缺点,引入了“通配符泛型”,针对上面的例子,使用通配泛型格式为<? extends Collection>,“?”代表未知类型,这个类型是实现Collection接口。
  1. public class CollectionGenFooDemo {
  2. public static void main(String args[]) {
  3. CollectionGenFoo<ArrayList> listFoo = null;
  4. listFoo = new CollectionGenFoo<ArrayList>(new ArrayList());
  5. CollectionGenFoo<? extends Collection> listFoo1 = null;
  6. listFoo1=new CollectionGenFoo<ArrayList>(new ArrayList());
  7. System.out.println("实例化成功!");
  8. }
  9. }
复制代码

注意:
1、如果只指定了<?>,而没有extends,则默认是允许Object及其下的任何Java类了。也就是任意类。
2、通配符泛型不单可以向下限制,如<? extends Collection>,还可以向上限制,如<? super Double>,表示类型只能接受Double及其上层父类类型,如Number、Object类型的实例。
3、泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定义泛型接口,泛型方法。这些都与泛型类中泛型的使用规则类似。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2