A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 何小红 中级黑马   /  2012-10-5 20:19  /  1463 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 何小红 于 2012-10-6 10:25 编辑

看张老师的视频,不知道泛型中的?的具体用法,有没高手解答一下?谢谢

<?>:不能肯定里面有什么东西,用?通配符可以引用其他各种参数化的类型,?通配符的定义的变量主要用作引用,可以调用与参数化方法,不能调用与参数化有关的方法。
它后面的具体用法?有没有对张老师的视频有深入理解的各位解释下,谢谢!

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 泛型教程里面很详细哦。

查看全部评分

8 个回复

倒序浏览
java高新技术,里有关于这个问题的说法。
一般有2种:<? extends Class1>  ?的类型最大不超过Class1类型
<? super Class2> ?的类型最小都超过Class2类型.
回复 使用道具 举报
以下是毕老师亲身经历上课 所记录总结的 希望帮主楼主 我是传智0703java基础班的学生呵呵 老毕带的班  如果楼主还需要什么可以M我 哈哈


泛型:
    它是jdk1.5版本,出现的技术,是一个安全机制。
   泛型技术的由来:
     集合中可以存储任意类型对象,但是在取出时,如果要使用具体对象的特有方法时,需要进行向下转型,
     如果存储的对象类型不一致,在转型过程中就会出现ClassCastException异常。
   在jdk1.5以后就有了解决方案,就是泛型技术。
   解决方案就是,在存储元素时,就不允许存储不同类型的元素。
   存储了就编译失败。
   
   所以就需要在存储元素时,在容器上明确具体的元素类型,这其实就和数组定义很像。
   
   好处:
    1,将运行时期的classcastException异常转移到了编译时期,进行检查,并以编译失败来体现。
    这样有利于程序员尽早解决问题。
    2,避免了向下转型(强转的)麻烦。
   
   
   什么时候写泛型呢?
   
    先简单理解:只要在使用类或者接口时,该类或者接口在api文档描述时都带着<>就需要在使用时,定义泛型。
    其实:泛型无非就是通过<>定义了一个形式参数,专门用于接收具体的引用类型。
    在使用时,一定要传递对应的实际参数类型。
    集合中泛型的应用特别多见。
   
   没有使用特有方法的 不需要强转的,正因为要使用特有方法 所以就要加泛型。
   
   泛型的擦除:
     泛型技术是用于编译时期的技术,这个技术是编译器里面融合进来了,生成后的class文件是不带泛型的。编译器会按照<>
     中的指定的类型对元素进行检查,检查不匹配,就编译失败,匹配,就编译通过,通过后生产的class文件中是没有泛型的。
   泛型的补偿:
     运行时,可以根据具体的元素对象获取其具体的类型,并用该类型对元素进行自动转换。
     
  泛型对于程序的设计也有一定优化动作。
  当一个类要操作的引用数据类型不确定的时候,可以将该类型定义一个形参。
  用到的这类时,有使用者来通过传递类型参数的形式,来确定要操作的具体的、
  对象类型。
  意味着:在定义这个类时候,需要在类上定义形参,用于接收具体的类型实参。   
  这就是泛型定义在类上, 这就是泛型类。
  
  什么时候使用泛型类呢? 只要类中操作的引用数据类型不确定的时候,就可以定义泛型类。
  
  有了泛型类,省去了曾经的强转和类型转换异常的麻烦。
  
  
  泛型除了 可以定义在类上 也可以定义在方法上。
  
  定义方法的是 在public加泛型。
   静态方法不可以访问类上定义的泛型,如果需要泛型,该泛型只能定义在方法上。 静态的泛型定义在返回值前面 ,类型的后面。  
  泛型也可以定义在接口上,只要类型不确定都可以写泛型。
  
   实现接口时,明确具体的类型。
   实现接口时候,也不明确具体的类型。  
通配符的应用:
  集合中使用的注意特点:保证两边一致。简单的定义方式就是保证两边类型一致,但是也有其他情况。
  泛型的通配符:?  类型不匹配时候用。当操作不同容器中类型都不确定的时候,而且使用的都是元素的从Object类中继承的方法。
  这时泛型就用通配符?来表示即可。
泛型的限定:
  明确具体类型代表一个类型,明确?代表所有类型,
  能不能对操作的类型限制在一个范围之内呢?
  
  比如:定义一个功能,只操作person类或者person子类型。这时可以用? 继承 E接收e类型或者E的子类型。
  存储时候就用这种方式。这就是上限。
  下限的表示形式: ? super E;接受E类型或者E的父类型。
      
什么时候使用上限呢? 一般情况下,只要是往容器中添加元素时,使用上限 ? extends  E
什么时候使用下限呢?一般情况下,只要是从容器中取出元素时,使用下限 ? super E   

回复 使用道具 举报
李志群 发表于 2012-10-5 22:32
以下是毕老师亲身经历上课 所记录总结的 希望帮主楼主 我是传智0703java基础班的学生呵呵 老毕带的班  如果 ...

呵呵谢谢你,我只是听张老师讲?的具体用法时没明白,我也是毕老师班上的,他说的我明白。就是那个?的具体用法,等号后面应该传什么类型什么的没有搞明白。上限下限都知道的。
回复 使用道具 举报
何小红 发表于 2012-10-5 23:05
呵呵谢谢你,我只是听张老师讲?的具体用法时没明白,我也是毕老师班上的,他说的我明白。就是那个?的具 ...

哦哦 不好意思 我没有看到那里呢嘿嘿 没帮上您忙哦
回复 使用道具 举报
这是那时学习老张基础加强的笔记:
泛型中的?通配符
定义一个方法打印一个集合中的内容
总结:
使用?通配符可以引用其他各种参数化的类型
,?通配符定义的变量主要用作引用,可以调用与参数化
无关的方法,不能调用与参数化有关的方法。
通配符扩展
限定通配符的上边界
Vector<? extends Number> x = new Vector<Integer>;正确
Vector<? extends Number> x = new Vector<String>;错误
限定符下边界
Vector<? super Integer> x = new Vector<Number>;正确
Vector<? super Integer> x = new Vector<Byte>;错误
Vectror<?> x;
Vector<Integer> y;
x = y;  可以;
y = x;不可以
回复 使用道具 举报
  1. package cn.itcast.heima.technology;

  2. import java.util.ArrayList;
  3. import java.util.Collection;


  4. public class ForGenericProblem {
  5.        
  6.        
  7.         public static void main(String[] args) {
  8.                
  9.                
  10.                 Collection<String> scol=new ArrayList<String>();
  11.                
  12.                 scol.add("zhangsan");
  13.                 scol.add("lisi");
  14.                 scol.add("wangwu");
  15.                
  16.                
  17.                 printCol1(scol);
  18.                
  19.                 System.out.println("----------------这是分割线----------------------------");
  20.                
  21.                 Collection<Integer> icol=new ArrayList<Integer>();
  22.                 icol.add(121);
  23.                 icol.add(2);
  24.                 icol.add(4);
  25.                
  26.                 printCol2(icol);
  27.                
  28.         }
  29.        
  30.         //在定义方法的时候,方便接受任何参数化类型的集合,定义泛型
  31.         public static<T> void printCol1(Collection<T> col){
  32.                
  33.                 //在方法中想要集合中的元素进行操作,如添加元素,
  34.                
  35.                 //col.add(new T());//帮助理解,事实不可以,会报错
  36.                
  37.                 /*在这里 ,需要的参数起码可以知道接收T类型的对象时没问题的。知道具体的类型T,姑且这么说吧
  38.                                         而在下面使用通配符"?"的方法泛型方法中因为不知道匹配的是什么类型化的参数
  39.                                         不可能使用到和参数化的类型有关的方法,因为你不能肯定是什么类型*/
  40.                
  41.                 //我是这么理解的,希望能够帮到你
  42.                
  43.                 col.size();//方法中没有涉及到和类型有关的参数
  44.                 for(T f:col){
  45.                         System.out.println(f);
  46.                 }
  47.         }
  48.        
  49.        
  50.         //这两种定义泛型的方法都是可以的,接受上面不同参数化 类型的集合
  51.        
  52.         public static void printCol2(Collection<?> col){
  53.                 col.add(null);
  54.                 /*无论add方法传入什么参数,都是错误的,在方法中传入的参数
  55.                  * 在使用通配符"?"的时候,不能调用任何与类型有关的方法
  56.                 */
  57.                 System.out.println(col.size());
  58.                 //无论什么类型的集合,都有方法size(),方法本身和类型无关
  59.                
  60.                 for(Object obj:col){
  61.                        
  62.                         System.out.println(obj);
  63.                 }
  64.         }

  65. }
  66. /*

  67. 在这里  ,
  68. 1,我顺便提个问题,就是上的两个printCol2方法中,当时张老师说无论什么参数都不可以,但是
  69. 如果是传入null的话,好像不会报错,

  70. 希望在这里看了张老师视频 的,哪位能给个解释,

  71. 2,而且上面的解释中,在方法printCol1中做不到添加元素,诚然这么理解了,个人以为。
  72. 希望哪位同样能给出答案,先谢谢了



  73. */
复制代码
回复 使用道具 举报
谢谢大家帮忙!很明白了,多谢啦
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马