jdk 1.5新特性——泛型

本文深入探讨了ASP.Net、Android、iOS开发以及.NET培训的相关技术,详细讲解了泛型的使用场景、好处、擦除与补偿机制、泛型类、泛型方法、泛型接口、泛型通配符以及在集合中的应用,旨在提供全面的技术指导与交流平台。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------

15,泛型

15.1泛型

泛型的符号:<泛型标识符,泛型标识符……>

泛型的作用:泛型就是用于接收具体引用数据类型的参数范围。

泛型什么时候用?

当操作的引用数据类型不确定的时候,就可以使用泛型。

使用泛型的好处:

1,将运行时期的问题转到的编译时期。

2,避免了强转的麻烦。

泛型是JDK1.5的新特性,目的是增加安全性。

15.2泛型的擦除和补偿

java源文件中定义的泛型在运行时会被擦除,生成的字节码文件是不带泛型的,称为泛型的擦除。

当在运行.class字节码文件时,会进行泛型的补偿,目的是避免使用者强转的动作。

泛型在集合、类、方法和接口中都有广泛的应用。

15.3泛型类

当类中操作的引用数据类型不确定时,就可以使用泛型类

类上定义泛型的格式:

权限饰符 class类名<泛型标识符1,泛型标识符2…….>{

                    …….CODE;

}

如:集合框架中的ArrayList<E>,定义了泛型,用来明确集合中要存放什么类型的元素,集合对象创建时需要传入具体的引用数据类型,一旦集合的泛型接收了具体的引用数据类型,那么这个集合中只能存储这一类型的元素,当传入其它类型的元素,编译器就会报错。

   ArrayList<String>al=new ArrayList<String>();

      //添加元素

      al.add("abc1");

      al.add("abc2");

      al.add("abc2");

      al.add("abc1");

      al.add("abc4");

      al.add("abc5");

for(Iterator<String> it=al.iterator();it.hasNext();){

      String s=it.next();//如果不加泛型就需要强转:String s=(String)it.next();

      System.out.println(s);

      }


 

如上,集合泛型为String类型,那么集合中的元素,就必须是这一类型,否则编译会报错,提高了安全性。

在元素的取出过程中,因为next()取出的元素类型默认是Object类型,如果加了泛型就不需要再进行强转的动作,否则必须要强转,避免了强转的麻烦。

如:以下自定义类中使用的泛型。

public class GenericDemo{

   public static void main(String[]args){

   Person<String,Integer> person=new Person<String,Integer>("lisi",23);//创建对象时指定具体泛型类型。

   Student<String,Integer> student=new student<String,Integer>("zhangsan",23,100);

      person.show();

      student.show();    

   }

}

class Person<N,A>{//Person类上定义了泛型

   private Aa;

   private Nn;

   Person(){

      

   }  

   Person(N n,A a){//构造参数使用了类上的泛型

      this.n=n;

      this.a=a;

   }  

   public void show(){

      System.out.println("姓名:"+this.n+" 年龄:"+this.a);

   }

}

class Student<N,A>extends Person<N,A>{//当子类继承父类时,没有传入具体泛型类型时,子类也要定义泛型 

   private A a;

   private N n;

   private int s;

   Student(N n, A a, int s) {

      this.n=n;

      this.a=a;

      this.s = s;

   }

   public void show(){

      System.out.println("姓名:"+this.n+"年龄:"+this.a+"分数:"+this.s);

   }  

}

/*

 姓名:lisi 年龄:23

姓名:zhangsan年龄:23分数:100

 */

15.4泛型方法

如果一个类定义了泛型,那么类中的方法可以使用类上的泛型作为参数。当然,如果方法中的参数类型不确定,则可以在方法上重新定义泛型。

注意:泛型在方法上的位置,只能定义在返回值的前面,修饰符的后面

格式:

权限修饰符 成员修饰符 <泛型标识符1,泛型标识符2……>返回值类型 方法名称(泛型标识符1 变量,泛型标识符2 变量,.....,其它参数{ 

            方法体;  

    }

如:

class Generic<T>{//定义了泛型的类

   private T  t;

   Generic(T t){

      this.t=t;

   }

   public void show_1(T t){//此方法的参数直接使用了类上的泛型,类上传入什么类型,这个方法的参数就是什么类型。

   }

   public <A> void show_2(A a){//此方法的参数,没有使用类上的泛型,而是使用了其他的泛型,则需要在方法上定义泛型。

   }

   public static <B> void show_3(B b){//注意,对于静态方法的参数是不能直接访问类上的泛型的,如果要使用泛型则需要在方法上重新定义泛型。

  }

}


注意:对于静态方法是不能直接访问类上的泛型的,因为类上的泛型是依赖对象的,而静态方法不需要对象去调用,所以,静态方法不能直接使用类上定义的泛型。如果静态方法要使用泛型,则需要在静态方法上定义泛型。

 

15.5泛型接口 

格式:

interface接口名<泛型标识符1,泛型标识符2……>{

}

如:

interface Inter<T>{

   void show(T t);

}


 

注意:如果一个类实现了带有泛型的接口时,如果没有明确具体泛型类型,则这个类也必须要定义泛型。

如:

interface Inter<T>{

   void show(T t);

}

class Generic <T> implements Inter<T>{//没有明确接口上泛型的具体类型,类也要定义泛型

 

   @Override

   public void show(T t) {

  }  

}

如果在实现一个泛型接口时,明确具体的泛型类型,就把具体的类型传给接口上的泛型。这样类上就需要再定义泛型。

如:

interface Inter<T>{

   void show(T t);

}

class Genericimplements Inter<String>{//明确接口上泛型的具体类型,直接传入具体类型到接口上的泛型。

 

   @Override

   publicvoid show(String t) {

  }  

}

 

15.6泛型通配符

泛型通配符:?表示未知的泛型类型。

用字母作为泛型标识符和泛型通配符?有什么区别呢?

用字母作为泛型的标识符,可以对其进行操作。

如:泛型方中,作为方法的返回值 ,作为一个类型,声明一个变量,传给类中的构造函数等等。

public <T> T show(T t){

//方法体;
}

 

而泛型通配符,代表未知的任意类型,是不能够直接操作的,通配符多用于对泛型的限定。

泛型的限定分为:上限和下限

上限:<? extends具体引用类型A> ,表示可以接收A类型及其A的子类类型。

下限:<? super具体引用类型B>,表示可以收的B类型及B的父类类型。

上限和下限同样可以用于对字母泛型标识符的限定。

 

如:上限

public class GenericDemo{

   public static void main(String[]args){

      new Generic().show("abc"); //传入字符串类型,可以打印

      new Generic().show(123);//传入其它类型,就报错。

   }

}

class Generic{

   public <T extends String> void show(T t){//show(T t)方法的参数类型T必须是,String及其子类,不能传入其它类型参数。

      System.out.println(t);

   }

}


 

如:下限

public class GenericDemo<T>{

   public static void main(String[]args){

      Person<String> p=new Person<String>("LISI",23);

      new Generic().show(p);

   }  

}

class Generic{

   public void show(Person<?super String> g){//此方法,用来接收Person类型 参数,对Person的泛型进行了下限。

      System.out.println(g.getT()+":"+g.getAge());

   }  

}

class Person<T>{

   private T t;

   private int age;

   public Person(T t,int age) {

      super();

      this.t = t;

      this.age = age;

   }

   

   public T getT() {

      return t;

   }

 

   public int getAge() {

     return age;

   }
}

15.7泛型在集合中的应用

泛型在集合中都有所应用,集合中使用泛型可以避免强转。集合定义泛型,在创建集合对象时,可以明确具体的泛型类型,元素在取出时,就不需再进行强转。

如:ArrayList集合

public class GenericDemo<T>{

   public static void main(String[]args){

      ArrayList al=newArrayList();//创建集合对象

      al.add("abc1");//add(Objectobj);方法中接收的参数都会被提升为Object类型。

      al.add("abc2");

      al.add("abc3");

      al.add("abc4");

      

      Iterator it=al.iterator();

      while(it.hasNext()){

         String s=(String)it.next();//添加的元素被提升为Object类型,取出时也是Object类型,要强转。

         System.out.println(s);

      }

   }  

}

因为没有加泛型,所以在元素取出时必须要强转。

把泛型加入集合:

:

import java.util.ArrayList;

import java.util.Iterator;

 

public class GenericDemo<T>{

   public static void main(String[]args){

      ArrayList<String> al=new ArrayList<String>();//创建集合对象,并明确泛型类型

      al.add("abc1");//add(Objectobj);方法中接收的参数都会被提升为Object类型。

      al.add("abc2");

      al.add("abc3");

      al.add("abc4");

      

      Iterator <String>it=al.iterator();//元素的取出明确泛型

      while(it.hasNext()){

         String s=it.next();//添加的元素被是String,取出时也是String类型,不需要强转。

         System.out.println(s);

      }

   }  

}


 

可见,泛型的应用,不仅可以对集合中元素的添加进行类型的限定,增强安全性,避免出错,而且避免了元素在取出中强转的麻烦。

---------------------- ASP.Net+Android+IOS开发.Net培训、期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值