java基础_10_泛型

泛型

JDK1.5版本以后出现的新特性,用于解决安全问题,是一个类型安全机制。

 

好处:

1,将运行时期出现问题ClassCastException 异常 转移到了编译时期

   方便于程序员解决问题,让运行时间问题减少,安全

2,避免了在重写比较器时的强制转换麻烦

 

泛型格式:

通过 < > 来定义要操作的引用数据类型。

 

泛型的限定:

 通配符,也可以理解为占位符。

 

? extends E  可以接收 及其子类。 称上限。

? super E    可以接收 及其父类。 称下限。

 

注意:像这种 ArrayList <Person>  al3 = new ArrayList <Student> ();

泛型里两边不一样是不是行的。必须是要一样的,子父类也不行。

 

泛型里的类型必须是引用类型,不能是基本数据类型,否则报错。

例:

public void method4(ArrayList < ? extends Person >  al) //此方法只能接收Person及其子类

{

  Iterator < ? extends Person>  it = al.iterator(); //迭代的时候也要加上泛型

  while (it.hasNext())

  {

     System.out.println(it.next().getName());

  }

}

 

public void method3(ArrayList< ? super Student> al) //此方法能接收Student及其父类

{

  Iterator< ? super Student>  it = al.iterator();

  while (it.hasNext())

 {

   System.out.println(it.next());

 }

}

 

public < T > void method2(ArrayList< T > al) //此方法可以适用于所有类型的ArrayList集合

{

  Iterator < T >  it = al.iterator();

  while (it.hasNext())

  {

    T t = it.next();  //好处是可以在此处控制

    System.out.println(t);

  }

}

 

public void method(ArrayList< ? >  al)  //此方法可以适用于所有ArrayList类型的集合

{

   Iterator < ? >  it = al.iterator();

   while (it.hasNext())

   {

     System.out.println(it.next());

   }

}

 

在使用java提供的对象时,什么时候写泛型呢?

 

通常在集合框架中很常见,只要见到 < > 就要定义泛型。

当使用集合时,将集合中要存储的数据类型作为参数传递到 < > 中即可。

 

其实 < > 就是用来接收类型的。

 

泛型类

泛型类定义的泛型,在整个类中有效,

如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了

 

      为了让方法可以操作不同类型,可以将泛型定义在方法上

 

特殊之处:

静态方法不可以访问类上定义的泛型。

如果想让静态方法操作不确定的应用数据类型,可以将泛型定义在静态方法上。 

 :

class Demo < T >

{

   public void show( T  t)

   {

     System.out.println("show:"+t);

   }

   public < T > void print( T t)

   {

      System.out.println("print:"+t);

   }

   public static < T > void method( T t)  //注意:泛型放在返回类型前面

   {

      System.out.println("static :"+t);

   }

}

建立对象如:Demo<String> d = new Demo<String>();

 

泛型定义在接口上

例:

    // 1,类实现泛型接口
    interface Inter < T >
    {
    	void show( T t);
    }
    class Inter2 implements Inter <String>  //在实现该接口的时候指明类型
    {
         public void show(String s)
    	   { 
    		System.out.println("show:"+s);
    	   }  
    }
    // 建立对象
    Inter2 i2 = new Inter2();
	
       // 2,泛型类实现泛型接口
       class InterImpl  < T >  implements Inter < T >
       {
	  public void show( T t)
	  {
	     System.out.println("InterImp<>+show:"+t);
	  }
        }
	
    // 建立对象
    InterImpl  < Integer >  al = new InterImpl < Integer > ();
    
    // 输出该集合元素
    Iterator < Integer >  it = al.iterator();  //迭代器也要带上泛型
    while (it.hasNext())
    {
        System.out.println(it.next().getName());
    }

 

通过反射来获取泛型的实际类型

如:Vector < Date >  v1  =  new Vector < Date >();

 

怎么拿到Date这个实际类型呢? 

把它转换成方法的参数就可以拿到,因为在编译的时候会去泛型化。

注意:

public void apply( Vector < Date >  v1)   {   }

                public void apply( Vector < String >  v1)  {   }

          这两种方法不是重载,编译不通过,因为它们是同一方法。因为会去泛型化,编译会去掉泛 型的限定

 

所以通过这点,我们就可以通过方法来获取泛型实际类型。

例:

  class Text{
    public void apply( Vector < Date >  v1)   {   }
    //通过字节码拿到方法
    Method  applyMethod = Text.class.getMethod(“apply” , Vector.class );
    
     //通过方法返回方法的形参类型保存至数组中
    Type []  types = applyMethod.getParameterTypes();
    
    //参数化类型,因为参数只有一个,我们取第一个元素即可。
    ParameterizedType pType = (ParameterizedType)types[0]; 
    
    //返回该参数的实际类型,因为参数类型也可能是多个(如:Map泛型有两个),所以这取第一个。
    System.out.println( pType.getActualTypeArguments()[0] );
    
  }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值