泛型(Generic)

Posted 胡广勤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了泛型(Generic)相关的知识,希望对你有一定的参考价值。

1.定义:一种特殊的变量,保存的是引用变量的类型
2.好处:避免数据类型的转换;将运行时期ClassCastException提前到编译时期
3.自定义带泛型的类:
     public class A<泛型名>{

    }
     注:类中凡是使用到数据类型的地方,都可以使用泛型名代替;
         泛型名自定义,但是将来使用者只能传递引用数据类型;

  1 代码实现:
  2 //自定义泛型类和泛型方法:
  3 class A<MM>{
  4 	private MM name;
  5 	private int age;
  6 
  7 	public MM getName(){
  8 		return name;
  9 	}
 10 	public void setName(MM name){
 11 		this.name = name;
 12 	}
 13 	public int getAge(){
 14 		return age;
 15 	}
 16 	public void setAge(int age){
 17 		this.age = age;
 18 	}
 19 
 20 	public void say(){
 21 		System.out.println(this.name+"\t"+this.age);
 22 	}
 23 
 24 	//定义一个带泛型的方法,传入一个QQ类型的值,返回一个QQ类型的值
 25 	public <QQ> QQ show(QQ m){
 26 		System.out.println(m);
 27 		return m;
 28 	}
 29 }
 30 
 31 public class MmDemo{
 32 	public static void main(String[] args){
 33 		//MM此处开始确定为String类型
 34 		A<String> a = new A<>();
 35 		a.setName("baobao");
 36 		a.setAge(24);
 37 		a.say();
 38 		//带泛型的show方法QQ此处定为String类型
 39 		a.show("xiaobao");//xiaobao
 40 		//带泛型的show方法QQ此处定为int类型
 41 		a.show(123);//123
 42 
 43 		A<String> b = new A<>();
 44 		b.setName("rongrong");
 45 		b.setAge(12);
 46 		b.say();
 47 
 48 	}
 49 }

4.自定义带泛型的方法:
     public <泛型名>泛型 getName(){
         return name;
     }
代码:见3.代码实现

5.自定义带泛型的接口:
     public interface B<泛型名>{

    }
     注:接口中凡是使用到数据类型的地方都可以使用泛型名代替;
代码实现:

给泛型赋值的格式有两种形式:
     (1)在定义子类的时候,直接给接口的泛型传递固定的数据类型;
     public class 类名 implements 接口名<具体的数据类型>{
         在类中但凡是使用到数据类型的地方,都可以使用泛型名代替;
     }
     (2)在定义子类的时候也不确定数据类型,在创建子类对象的时候,确定数据类型
     public class 类名<泛型名B> implements 接口名<泛型名B>{
         在类中但凡是使用到数据类型的地方,都可以使用泛型名代替;
     }

  1 //定义一个带泛型的接口
  2 	interface A<W>{
  3 		//带泛型参数的show方法,抽象方法
  4 		public abstract void show(W w);
  5 	}
  6 
  7 	//定义一个实现类--带泛型的实现类
  8 	class BImpl<W> implements A<W>{	//类名后需加上与接口一致的泛型名
  9 		@Override
 10 		public void show(W w){	//重写了带泛型的方法
 11 			System.out.println(w);
 12 		}
 13 
 14 		public static void main(String[] args){
 15 			BImpl<String> b = new BImpl<>();
 16 			b.show("baobao");	//baobao
 17 
 18 			BImpl<Integer> a = new BImpl<>();
 19 			a.show(12345);	//12345
 20 		}
 21 	}

6.泛型通配符:?
创建带泛型的类的对象的时候,泛型不能使用多态;只能使用通配符的形式,来达到这样的效果;

具体的通配符的符号:?  代表任意数据类型
对通配符的范围进行限定:
     ? extends 具体的数据类型A   此时是限定了上限;A类或A类的子类符合要求,其他数据类型不能传递;
     ? super   具体的数据类型A   此时是限定了下限;A类或A类的父类符合要求,其他数据类型不能传递;

代码实现:

  1 import java.util.List;
  2 	import java.util.ArrayList;
  3 	//定义一个父类
  4 	class Father{
  5 
  6 	}
  7 
  8 	//定义一个子类
  9 	class Son extends Father{
 10 
 11 	}
 12 
 13 	//定义一个测试类
 14 	public class FsDemo{
 15 		public static void main(String[] args){
 16 			//分别使用Object Father Son作为泛型,定义list集合
 17 			List<Object> Biggest = new ArrayList<>();
 18 			List<Father> Bigger = new ArrayList<>();
 19 			List<Son> Big = new ArrayList<>();
 20 
 21 			//method1(Biggest);//错误: 不兼容的类型: List<Object>无法转换为List<? extends Father>
 22 			method1(Bigger);	//safe extends
 23 			method1(Big);	//safe extends
 24 
 25 			method2(Biggest);	//safe super
 26 			method2(Bigger);	//safe super
 27 			//method2(Big);//错误: 不兼容的类型: List<Son>无法转换为List<? super Father>
 28 
 29 		}
 30 			//定义带泛型的method1方法,上限为Father--? extends Father
 31 			public static void method1(List<? extends Father> list){
 32 				System.out.println("safe extends");
 33 			}
 34 
 35 			//定义带泛型的method2方法,下限为Father--? super Father
 36 			public static void method2(List<? super Father> list){
 37 				System.out.println("safe super");
 38 			}
 39 	}

以上是关于泛型(Generic)的主要内容,如果未能解决你的问题,请参考以下文章

Generic(泛型)

详解 Java 泛型(Generic)机制

详解 Java 泛型(Generic)机制

详解 Java 泛型(Generic)机制

你真的了解泛型 Generic 嘛?

c#之泛型详解(Generic)