Java.泛型


概念

  • 泛型(JDK1.5后引入),即“参数化类型”,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
  • 泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的。
  • 类型参数的意义是告诉编译器这个集合中要存放实例的类型,从而在添加其他类型时做出提示,在编译时就为类型安全做了保证。
  • 这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类泛型接口泛型方法

泛型类

  • 泛型类型用于类的定义中,被称为泛型类。通过泛型可以完成对一组类的操作对外开放相同的接口。

  • 泛型接口在接口名后添加类型参数列表,比如 < T >,<>内的泛型标识可以随便写,多个参数之间用逗号隔开。

  • 泛型类的语法格式:

    class 类名称 <T1,T1>{
     
      private T1  a;
      private T2  b; 
      ...	
     
    }
    
  • 示例

    class C<T1,T2>{	
    	T1 a;
    	T2 b;
    	public C(T1 a,T2 b){
    		this.a = a;
    		this.b = b;
    	}
    	public T1 get1(){
    		return a;
    	}
    	public T2 get2(){
    		return b;
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {		
    		C<String,String> c1 = new C<String,String>("Java是世界上最好的语言",".cpp");
    		System.out.println("a:"+c1.get1());
    		System.out.println("b:"+c1.get2());
    		System.out.println(c1.get1() + c1.get2()); 
    		
    		C<Integer,Integer> c2 = new C<Integer,Integer>(666,999);
    		System.out.println("a="+c2.get1());
    		System.out.println("b="+c2.get2());
    		System.out.println("a+b=" + (c2.get1() + c2.get2())); //泛型在旧版本不可以相加,现在可以相加
    	}
    }
    
    
  • 输出:

    a:Java是世界上最好的语言
    b:.cpp
    Java是世界上最好的语言.cpp
    a=666
    b=999
    a+b=1665
    

泛型接口

  • 和泛型类一样,泛型接口在接口名后添加类型参数列表

  • 格式

    public interface 接口名<T> {
        public T fun();
    }
    
  • 示例:

    interface I<T>{
    	abstract void printI(T t);
    }
    
    abstract class CA<T>{	
    	T a;
    	public CA(T a){
    		this.a = a;
    	}
    	public T get1(){
    		return a;
    	}
    	abstract void printCA();	
    }
    
    class CB<T,T2,T3> extends CA<T> implements I<T3>{	//继承CA,实现I
    	T2 b;
    	public CB(T a,T2 b){
    		super(a);
    		this.b = b;
    	}
    	public T2 get2(){
    		return b;
    	}
    	
    	void printCA() {
    		System.out.println("泛型类可以继承泛型类");
    	}
    	
    	public void printI(T3 t) {
    		System.out.println(t);
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {		
    		CB<Integer,String,String> c = new CB<Integer,String,String>(666,"NB");
    		c.printCA();
    		System.out.println(c.get2() + c.get1());
    		
    		c.printI("接口");
    	}
    }
    
    
  • 输出

    泛型类可以继承泛型类
    NB666
    接口	
    

泛型方法

  • 泛型方法,是在调用方法的时候指明泛型的具体类型 。定义泛型方法只需要在方法返回值前添加类型参数列表。

    public <T> void fun(){
    	//...
    }
    
    
  • 示例

    class C{
    	//泛型方法
    	public <T> void PrinInfo(T t){
    		System.out.println(t);
    	}
    	//泛型方法的重载
    	public <T1,T2> void PrinInfo(T1 t,T2 t2){
    		System.out.println(t);
    		System.out.println(t2);
    	}
    }
    public class Test {
    	public static void main(String[] args) {		
    		C c = new C();
    		c.PrinInfo("少壮不努力","老大徒伤悲");	//可以使用任何类型
    		c.PrinInfo(666);
    		c.PrinInfo(3.1415926);
    	}
    }
    
    
  • 输出:

    少壮不努力
    老大徒伤悲
    666
    3.1415926
    

限制泛型的使用类型

  • 当没有指定泛型继承的类型或接口时,默认使用extends Objext,所以默认情况下任何类型都可以做为参数传入

  • 在定义泛型类别时,如果想要限制使用泛型类型时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是某个特定类型继承某个类,或者实现某个接口

  • 示例:

    class C<T extends String>{	//限制类型
    	T a;
    	public C(T a){
    		this.a = a;
    	}
    	public T getData(){
    		return a;
    	}
    }
    
    public class Test {
    	public static void main(String[] args) {		
    		C<String> c = new C<String>("我现在只能是字符串哦");	//只能是String类型
    		System.out.println(c.getData());;
    	}
    }
    
    

泛型的通配符

  • 有时候希望传入的类型有一个指定的范围,从而可以进行一些特定的操作。

  • 无限制通配符 < ?>:要使用泛型,但是不确定或者不关心实际要操作的类型,可以使用无限制通配符。

  • 上界通配符 < ? extends E>:在类型参数中使用 extends 表示这个泛型中的参数必须是 E 或者 E 的子类。

  • 下界通配符 < ? super E>:在类型参数中使用 super 表示这个泛型中的参数必须是 E 或者 E 的父类。

  • 示例

    class Animal{
    	public void eat(){
    		System.out.println("不同的动物有不同的吃法");
    	}
    }
    
    class Dog extends Animal{
    	public void eat(){
    		System.out.println("啃骨头");
    	}
    }
    
    
    class erha extends Dog{
    	public void eat(){
    		System.out.println("吃沙发");
    	}
    }
    
    class C<T>{	
    	T a;
    	
    	void print(){
    		System.out.println("a:"+a);
    	}
    	
    	C(T a){
    		this.a = a;
    	}
    }
    public class Test {
    	public static void main(String[] args) {
    		C<Animal> c1 = new C(new Animal());
    		C<Dog> c2 = new C(new Dog());
    		C<erha> c3 = new C(new erha());
    		C<String> c4 = new C("我是一个字符串");
    		
    		C<?> c5;
    		C<? extends Dog> c6;
    		C<? super Dog> c7;
    		
    		c5 = c1;
    		c5 = c2;
    		c5 = c3;
    		c5 = c4;
    		
    		c6 = c2;
    		c6 = c3;
    		
    		c7 = c1;
    		c7 = c2;
    	}
    }
    
    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

money的大雨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值