Loading...
墨滴

莫激

2021/12/14  阅读:30  主题:默认主题

泛型约束

泛型约束

什么是泛型约束

  • 让泛型的类型有一定的限制

关键字:where

泛型约束一共有6中

  1. 值类型 where 泛型字母:struct 比如:where T:struct
  2. 引用类型 where 泛型字母:class 比如:where T:class
  3. 存在无参公共构造函数 where 泛型字母:new() 比如: where T:new()
  4. 某个类本身或者其派生类 where 泛型字母:类名 比如:where T:类名
  5. 某个接口的派生类型 where 泛型字母:接口名 比如:where T:接口名
  6. 另一个泛型类型本身或者派生类型 where 泛型字母:另一个泛型字母 比如:where T另一个泛型字母

基本语法

where 泛型字母:(约束的类型)

各类型的约束讲解

值类型约束

  • 泛型传入的时候,必须是值类型,where T:struct
//这样约束后,代表这个T一定是结构类型,也就是值类型,比如int、float
class Test1<Twhere T:struct
{
    //泛型变量
    public T value;
    //约束泛型方法
    public void TestFun<K>(K v) where K:struct
    {
    }
    
    public static void main(String[]args)
    {
        这是错误的!!Test1<Object> t1 = new Test1<Object>();这是错误的!!!会报错
     Test1<int> t1 = new Test1<int>(); //这样才是对的    
        t1.TestFun<Object>(Object v);也是错误的!!!//Object是引用类型
        t1.TestFun<int>(int v);//这样才对
    }
}

引用类型约束

  • 泛型传入的时候,该类必须是引用类型,where T:class
//约束Test2类中的泛型只能是引用类型
class Test2<Twhere T:class
{
   //泛型变量
    public T value;
    //约束泛型方法
    public void Test2Fun<K>(K k) where K:class
    { 
    }
  
    public static void main(String[]args)
    {
        //尖括号里只能写引用类型,不然会报错
        Test2<Randow> t2 = new Test2<Randow>();
        t2.value = new Randow();
        t2.Test2Fun<Object>(new Object());
    }
}

公共无参构造约束

  • 当传入泛型的时候,该类必须是有无参构造函数、是个公共的、是非抽象类的where T:new()
class Test1
{  
}
class Test2
{
    //写有参构造函数可以把无参给顶替掉,因此Test2就没有无参构造了
    public Test2(int a)
    {
    }
}
//这里的T必须是无参、公共的、非抽象类,因为抽象类是不能被new的
class Test3<Twhere T:new() 
{
    public T value;
    public void Test3Fun<K>(K k) where K:new()
    {   
    }       
}

public static void main(String[]args)
{
    Test3<Test1> t3 = new Test3<Test1>();//Test1中有无参公共函数、是public的
    Test3<Test2> t3 = new Test3<Test2>();//这个是错误的,因为Test2中没有无参构造,被有参顶替掉了,所以会报错
}

类约束

  • 泛型传入的时候,必须是该类名或者是其派生类where T:类名
class Test1
{}
class Test3:Test1
{}  
class Test4<Twhere t:Test1//约束T要么是Test1类的或者是Test1的派生类
{
 public T value
 public void Test4Fun<K>(K k)where K:Test1
    {
     
    }
    
    public static void main(Stirng[]args)
    {
     Test4<Test1> t4 = new Test4<Test1>();
     Test4<Test3> t4 = new Test4<Test3>();//这个可行是因为Test3是Test1的派生类
    }
}

接口约束

  • 泛型传入时候,必须是接口或者继承该接口或者接口派生的接口的类名,where T:接口名

    interface Ifly
    { }
    class Test4:Ifly
    { }
    class Test5<Twhere T:Ifly
    {
     public T value;
     public void Test5Fun<K>(K k) where K:Ifly
     {}
    }

    public static void main(String[]args)
    {
        Test5<Ifly> t5 = new Test5<Ifly>();//因为Ifly刚好是接口所以成立
        Test5<Test4> t5 = new Test5<Test4>();//这是因为Test4类继承了接口Ifly,所以成立
        t5.value = new Test4();
    }

另一个泛型约束

  • 泛型传入时,必须是指定的泛型类型本身或者是派生类型,where T另一个泛型字母
//这里约束后,T要不就是跟U一样的,要不就是是U的派生类型
class Test6<T,Uwhere T:U 
{
 public T value;
 public void Test6Fun<K,V>(K k) where K:V
 {}
}

public static void main(String[]args)
{
    //这里Test4继承了Ifly接口
    Test6<Test4,Ifly> t6 = new Test6<Test4,Ifly>();
    //这样也是可以的,前面说了都是一样的也是可以的
    Test6<Test4,Test4>t6 = new Test6<Test4,Test4>();
}

约束的组合使用

  • 需要注意的是new()要放在后面,不让会报错,怎么组合可以进行尝试,没必要去记
class Test7<Twhere T:class,new()
{}

多个泛型有约束

  • 多个泛型有不一样的约束时,就这么写,注意where之间没有逗号没有分号,直接空开就行
class Test8<T,K>where Tclass,new() where K:struct
{}

总结

  • 泛型约束:让类型由一定限制
  • class
  • struct
  • new()
  • 类名(本身类或者派生类)
  • 接口名(本身接口或者继承该接口的类名)
  • 另一个泛型字母

莫激

2021/12/14  阅读:30  主题:默认主题

作者介绍

莫激