`
cary
  • 浏览: 84270 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
社区版块
存档分类
最新评论

泛型 <T> 详解

    博客分类:
  • J2EE
阅读更多

 引用。原地址:http://www.java3z.com/cwbwebhome/article/article5/tiger2.jsp

清单 1
// 一个简单的范型类. 
// 这里,T 是一个类型参数,当创建Gen类的对象时将被真实的类型取代.
public class Gen< T> {
  T ob; // 声明一个T类型的对象
  

  Gen(T o) {
    ob = o;
  }


  public T getob() {
    return ob;
  }

  // 输出T的类型
public  void showType() {
    System.out.println("Type of T is " +
                       ob.getClass().getName());
  }
}

// 示范这个范型类的用法
public class GenDemo {
  public static void main(String args[]) {
    // 声明一个类型参数为Integers的Gen对象 
    Gen< Integer> iOb; 

    // 创建一个Gen< Integer> 对象并分配其引用到iOb.  注意使用了自动装箱.
    iOb = new Gen< Integer>(88);

    // 显示类型
    iOb.showType();

    // 获取在iOb对象内的值,注意不需要类型转换.
 
    int v = iOb.getob();
    System.out.println("value: " + v);

    System.out.println();

    // 创建一个类型参数为String的Gen对象
    Gen< String> strOb = new Gen< String>("Generics Test");

  
    strOb.showType();

  
    String str = strOb.getob();
    System.out.println("value: " + str);
  }
}

清单2
// NonGen类没有使用范型, 与使用范型的Gen的等价
class NonGen { 
  Object ob; // ob 现在是一个Object类型
   
 
  NonGen(Object o) { 
    ob = o; 
  } 
 
  // 返回类型为 Object.
  Object getob() { 
    return ob; 
  } 

  // 显示ob的类型. 
  void showType() { 
    System.out.println("Type of ob is " + 
                       ob.getClass().getName()); 
  } 

 
// 示范这个类用使用. 
class NonGenDemo { 
  public static void main(String args[]) { 
    NonGen iOb;  
 
   
    // 自动装箱还会发生.
    iOb = new NonGen(88); 
 
  
    iOb.showType();

    // 输出iOb的值,必须进行类型转换
    int v = (Integer) iOb.getob(); 
    System.out.println("value: " + v); 
 
    System.out.println(); 
 

    // 创建另一个对象,存字符串.
    NonGen strOb = new NonGen("Non-Generics Test"); 
 
    strOb.showType();

    String str = (String) strOb.getob(); 
    System.out.println("value: " + str); 

    // 下面这句编译能通过,因为没有语法错误
    iOb = strOb;
    v = (Integer) iOb.getob(); // 发生运行时错误!
  } 
}

清单 3
//带两个类型参数的范型
class TwoGen< T, V> {
  T ob1;
  V ob2;
  

  TwoGen(T o1, V o2) {
    ob1 = o1;
    ob2 = o2;
  }

  // 显示T 和 V的类型.
  void showTypes() {
    System.out.println("Type of T is " +
                       ob1.getClass().getName());

    System.out.println("Type of V is " +
                       ob2.getClass().getName());
  }

  T getob1() {
    return ob1;
  }

  V getob2() {
    return ob2;
  }
}

// 示范.
class SimpGen {
  public static void main(String args[]) {

    TwoGen< Integer, String> tgObj =
      new TwoGen< Integer, String>(88, "Generics");

    tgObj.showTypes();

    // 获取并显示值.
    int v = tgObj.getob1();
    System.out.println("value: " + v);

    String str = tgObj.getob2();
    System.out.println("value: " + str);
  }
}

清单 4
// 尝试创建一个能计算数字平均值的泛型类
// 这个类包括一个错误!
class Stats< T> { 
  T[] nums; // nums 是一个T类型的数组
   
 
  Stats(T[] o) { 
    nums = o; 
  } 
 
  // 所有的情况下都返回double.
  double average() { 
    double sum = 0.0;

    for(int i=0; i < nums.length; i++) 
      sum += nums[i].doubleValue(); // 错误!!!,编译器无法知道你只使用数字类型创建Stats对象.

    return sum / nums.length;
  } 
}

清单 5
// 这次使用有界类型的范型,声明一个上界,所有类型变量必须从超类派生.
class Stats< T extends Number> { 
  T[] nums; // Number或它的子类型的数组
   

  Stats(T[] o) { 
    nums = o; 
  } 
 
  double average() { 
    double sum = 0.0;

    for(int i=0; i < nums.length; i++) 
      sum += nums[i].doubleValue();

    return sum / nums.length;
  } 

 
// 示范 
class BoundsDemo { 
  public static void main(String args[]) { 

    Integer inums[] = { 1, 2, 3, 4, 5 };
    Stats< Integer> iob = new Stats< Integer>(inums);  
    double v = iob.average();
    System.out.println("iob average is " + v);

    Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 };
    Stats< Double> dob = new Stats< Double>(dnums);  
    double w = dob.average();
    System.out.println("dob average is " + w);

    // 这不能编译,因为String不是Number的子类
    // String strs[] = { "1", "2", "3", "4", "5" };
    // Stats< String> strob = new Stats< String>(strs);  
 
    // double x = strob.average();
    // System.out.println("strob average is " + v);

  } 
}

清单 6
// 使用通配符
class Stats< T extends Number> {  
  T[] nums;
    
 
  Stats(T[] o) {  
    nums = o;  
  }  
  
  double average() {  
    double sum = 0.0; 
 
    for(int i=0; i < nums.length; i++)  
      sum += nums[i].doubleValue(); 
 
    return sum / nums.length; 
  }

  // 确定两个包含数组的Stats对象是否有相同的平均值.
  // 注意使用通配符
  boolean sameAvg(Stats< ?> ob) {
    if(average() == ob.average()) 
      return true;

    return false;
  }
}  
  
// 示范.
class WildcardDemo {  
  public static void main(String args[]) {  
    Integer inums[] = { 1, 2, 3, 4, 5 }; 
    Stats< Integer> iob = new Stats< Integer>(inums);   
    double v = iob.average(); 
    System.out.println("iob average is " + v); 
 
    Double dnums[] = { 1.1, 2.2, 3.3, 4.4, 5.5 }; 
    Stats< Double> dob = new Stats< Double>(dnums);   
    double w = dob.average(); 
    System.out.println("dob average is " + w); 
 
    Float fnums[] = { 1.0F, 2.0F, 3.0F, 4.0F, 5.0F }; 
    Stats< Float> fob = new Stats< Float>(fnums);   
    double x = fob.average(); 
    System.out.println("fob average is " + x); 
 
    // 看哪二个数组有相同的平均值.
    System.out.print("Averages of iob and dob ");
    if(iob.sameAvg(dob))
      System.out.println("are the same."); 
    else
      System.out.println("differ."); 

    System.out.print("Averages of iob and fob ");
    if(iob.sameAvg(fob))
      System.out.println("are the same."); 
    else
      System.out.println("differ."); 
  }  
}

运行结果:

C:\java>java   WildcardDemo
iob average is 3.0
dob average is 3.3
fob average is 3.0
Averages of iob and dob differ.
Averages of iob and fob are the same.


listing 7
// 有界通配符.

// 二维空间.
class TwoD {
  int x, y;

  TwoD(int a, int b) {
    x = a;
    y = b;
  }
}

// 三维空间.
class ThreeD extends TwoD {
  int z;
  
  ThreeD(int a, int b, int c) {
    super(a, b);
    z = c;
  }
}

// 四维空间.
class FourD extends ThreeD {
  int t;

  FourD(int a, int b, int c, int d) {
    super(a, b, c);
    t = d; 
  }
}

class Coords< T extends TwoD> { //有界范型
  T[] coords;

  Coords(T[] o) { coords = o; }
}

// 示范.
class BoundedWildcard {
  static void showXY(Coords< ?> c) {
    System.out.println("X Y Coordinates:");
    for(int i=0; i < c.coords.length; i++)
      System.out.println(c.coords[i].x + " " +
                         c.coords[i].y);
    System.out.println();
  }

  static void showXYZ(Coords< ? extends ThreeD> c) {
    System.out.println("X Y Z Coordinates:");
    for(int i=0; i < c.coords.length; i++)
      System.out.println(c.coords[i].x + " " +
                         c.coords[i].y + " " +
                         c.coords[i].z);
    System.out.println();
  }

  static void showAll(Coords< ? extends FourD> c) {
    System.out.println("X Y Z T Coordinates:");
    for(int i=0; i < c.coords.length; i++)
      System.out.println(c.coords[i].x + " " +
                         c.coords[i].y + " " +
                         c.coords[i].z + " " +
                         c.coords[i].t);
    System.out.println();
  }

  public static void main(String args[]) {
    TwoD td[] = {
      new TwoD(0, 0),
      new TwoD(7, 9),
      new TwoD(18, 4),
      new TwoD(-1, -23)
    };

    Coords< TwoD> tdlocs = new Coords< TwoD>(td);    

    System.out.println("Contents of tdlocs.");
    showXY(tdlocs); // OK, is a TwoD
//  showXYZ(tdlocs); // Error, not a ThreeD
//  showAll(tdlocs); // Erorr, not a FourD

    // 创建一些四维点
    FourD fd[] = {
      new FourD(1, 2, 3, 4),
      new FourD(6, 8, 14, 8),
      new FourD(22, 9, 4, 9),
      new FourD(3, -2, -23, 17)
    };

    Coords< FourD> fdlocs = new Coords< FourD>(fd);    

    System.out.println("Contents of fdlocs.");
    //这些都不会产生错误.
    showXY(fdlocs); 
    showXYZ(fdlocs);
    showAll(fdlocs);
  }
}

清单 8
// 示范简单的范型方法
class GenMethDemo { 

  // 静态的范型方法,测试一个对象是否在一个数组中.
  static < T, V extends T> boolean isIn(T x, V[] y) {

    for(int i=0; i < y.length; i++)
      if(x.equals(y[i])) return true;

    return false;
  }

  public static void main(String args[]) { 

    // 对Integers使用isIn()方法.
    Integer nums[] = { 1, 2, 3, 4, 5 };

    if(isIn(2, nums))
      System.out.println("2 is in nums");

    if(!isIn(7, nums))
      System.out.println("7 is not in nums");

    System.out.println();

    // 对Strings使用isIn()
    String strs[] = { "one", "two", "three",
                      "four", "five" };

    if(isIn("two", strs))
      System.out.println("two is in strs");

    if(!isIn("seven", strs))
      System.out.println("seven is not in strs");

    // 不能编译,类型必须一致.
    //    if(isIn("two", nums))
    //      System.out.println("two is in strs");
  } 
}

清单 9
// 泛型构造器.
class GenCons {
  private double val;

  < T extends Number> GenCons(T arg) {
    val = arg.doubleValue();
  }

  void showval() {
    System.out.println("val: " + val);
  }
}

class GenConsDemo {
  public static void main(String args[]) {

    GenCons test = new GenCons(100);
    GenCons test2 = new GenCons(123.5F);

    test.showval();
    test2.showval();
  }
}
运行结果:
C:\java>java   GenConsDemo
val: 100.0
val: 123.5

清单 10
// 一个泛型接口的例子.

// 来用返回某个对象集的最小或最大值.
interface MinMax< T extends Comparable< T>> {
  T min();
  T max();
}

//MyClass实现接口MinMax
class MyClass< T extends Comparable< T>> implements MinMax< T> {
  T[] vals;

  MyClass(T[] o) { vals = o; }

  // 返回最小值.
  public T min() {
    T v = vals[0];

    for(int i=1; i < vals.length; i++)
      if(vals[i].compareTo(v) < 0) v = vals[i];

    return v;
  }

  // 返回最大值.
  public T max() {
    T v = vals[0];

    for(int i=1; i < vals.length; i++)
      if(vals[i].compareTo(v) > 0) v = vals[i];

    return v;
  }
}

class GenIFDemo {
  public static void main(String args[]) {
    Integer inums[] = {3, 6, 2, 8, 6 };
    Character chs[] = {'b', 'r', 'p', 'w' };

    MyClass< Integer> iob = new MyClass< Integer>(inums);
    MyClass< Character> cob = new MyClass< Character>(chs);

    System.out.println("Max value in inums: " + iob.max());
    System.out.println("Min value in inums: " + iob.min());

    System.out.println("Max value in chs: " + cob.max());
    System.out.println("Min value in chs: " + cob.min());
  }
}

清单 11
// 示范使用原始类型. 一个泛型类在使用时可以不带类型参数,同时带来的是失去了类型安全.
class Gen< T> { 
  T ob; // 声明一个T类型的对象
   
  Gen(T o) { 
    ob = o; 
  } 
 
  T getob() { 
    return ob; 
  } 

 
// 使用原始类型.
class RawDemo { 
  public static void main(String args[]) { 

    Gen< Integer> iOb = new Gen< Integer>(88); 
  
    Gen< String> strOb = new Gen< String>("Generics Test"); 
 
    // 创建一个使用原始类型参数的Gen
    Gen raw = new Gen(new Double(98.6));

    // 类型转换是必须的
    double d = (Double) raw.getob();
    System.out.println("value: " + d);

    //int i = (Integer) raw.getob(); // 运行时错误

    strOb = raw; // 可以通过编译
    // String str = strOb.getob(); // 运行时错误 
    
    raw = iOb; // 可能编译
    // d = (Double) raw.getob(); // 运行时错误
  } 
}

清单 12
// 泛型类层次. 使用泛型超类
class Gen< T> { 
  T ob;
   
  Gen(T o) { 
    ob = o; 
  } 
 
  // Return ob. 
  T getob() { 
    return ob; 
  } 


// Gen的子类
class Gen2< T> extends Gen< T> {
  Gen2(T o) {
    super(o);
  }
}

清单 13
// 子类能增加自己的类型参数.
class Gen< T> { 
  T ob;
   
  Gen(T o) { 
    ob = o; 
  } 
 
  T getob() { 
    return ob; 
  } 


class Gen2< T, V> extends Gen< T> {
  V ob2;

  Gen2(T o, V o2) {
    super(o);
    ob2 = o2;
  }

  V getob2() {
    return ob2;
  }
}
 
// 创建一个Gen2类型的对象.
class HierDemo { 
  public static void main(String args[]) { 
   
    Gen2< String, Integer> x = new Gen2< String, Integer>("Value is: ", 99); 

    System.out.print(x.getob());
    System.out.println(x.getob2());
  } 
}

清单 14
// 泛型子类

class NonGen {
  int num;

  NonGen(int i) {
    num = i;
  }

  int getnum() {
    return num;
  }
}

// 一个泛型子类
class Gen< T> extends NonGen { 
  T ob;
   
  Gen(T o, int i) { 
    super(i);
    ob = o; 
  } 
 
  T getob() { 
    return ob; 
  } 

 
class HierDemo2 { 
  public static void main(String args[]) { 
   
    Gen< String> w = new Gen< String>("Hello", 47);
   
    System.out.print(w.getob() + " ");
    System.out.println(w.getnum());
  } 
}

清单 15
// 泛型层次中的运行时类型比较. 
class Gen< T> {  
  T ob; 
    
  Gen(T o) {  
    ob = o;  
  }  
  
  T getob() {  
    return ob;  
  }  
}  
 
// Gen的子类. 
class Gen2< T> extends Gen< T> { 
  Gen2(T o) { 
    super(o); 
  } 

 
class HierDemo3 {  
  public static void main(String args[]) {  
    
    // Create a Gen object for Integers. 
    Gen< Integer> iOb = new Gen< Integer>(88); 
 
    // Create a Gen2 object for Integers. 
    Gen2< Integer> iOb2 = new Gen2< Integer>(99);  
   
    // Create a Gen2 object for Strings. 
    Gen2< String> strOb2 = new Gen2< String>("Generics Test");  
 
    // See if iOb2 is some form of Gen2.
    if(iOb2 instanceof Gen2< ?>)  
      System.out.println("iOb2 is instance of Gen2"); 

    // See if iOb2 is some form of Gen.
    if(iOb2 instanceof Gen< ?>)  
      System.out.println("iOb2 is instance of Gen"); 
 
    System.out.println(); 
 
    // See if strOb2 is a Gen2.
    if(strOb2 instanceof Gen2< ?>)  
      System.out.println("strOb is instance of Gen2"); 
 
    // See if strOb2 is a Gen.
    if(strOb2 instanceof Gen< ?>)  
      System.out.println("strOb is instance of Gen"); 

    System.out.println(); 
 
    // See if iOb is an instance of Gen2, which its not.
    if(iOb instanceof Gen2< ?>)  
      System.out.println("iOb is instance of Gen2"); 
 
    // See if iOb is an instance of Gen, which it is.
    if(iOb instanceof Gen< ?>)  
      System.out.println("iOb is instance of Gen"); 
 
    // The following can't be compiled because 
    // generic type info does not exist at runtime.
    // if(iOb2 instanceof Gen2< Integer>)  
    // System.out.println("iOb2 is instance of Gen2< Integer>"); 
  }  
}

运行结果:

C:\java>java     HierDemo3
iOb2 is instance of Gen2
iOb2 is instance of Gen

strOb is instance of Gen2
strOb is instance of Gen

iOb is instance of Gen

listing 16
// 重写泛型类中的方法
class Gen< T> { 
  T ob;

  Gen(T o) { 
    ob = o; 
  } 
 
 
  T getob() { 
    System.out.print("Gen's getob(): " );
    return ob; 
  } 


// Gen的子类重写了getob().
class Gen2< T> extends Gen< T> {

  Gen2(T o) {
    super(o);
  }
  
  T getob() { 
    System.out.print("Gen2's getob(): ");
    return ob; 
  } 
}
 
// 演示重写泛型方法.
class OverrideDemo { 
  public static void main(String args[]) { 
   
    // Create a Gen object for Integers.
    Gen< Integer> iOb = new Gen< Integer>(88);

    // Create a Gen2 object for Integers.
    Gen2< Integer> iOb2 = new Gen2< Integer>(99); 
  
    // Create a Gen2 object for Strings.
    Gen2< String> strOb2 = new Gen2< String>("Generics Test"); 

    System.out.println(iOb.getob());
    System.out.println(iOb2.getob());
    System.out.println(strOb2.getob());
  } 
}
运行结果:

C:\java>java   OverrideDemo
Gen's getob(): 88
Gen2's getob(): 99
Gen2's getob(): Generics Test


清单 17
// 不使用泛型,迭代一个collection.
import java.util.*;

class OldStyle { 
  public static void main(String args[]) {
    ArrayList list = new ArrayList();

    list.add("one");
    list.add("two");
    list.add("three");
    list.add("four");

    Iterator itr = list.iterator();
    while(itr.hasNext()) {

    
      String str = (String) itr.next(); // 这里需要类型转换.

      System.out.println(str + " is " + str.length() + " chars long.");
    }
  } 
}

清单 18
// 新的泛型版本.
import java.util.*;

class NewStyle { 
  public static void main(String args[]) {

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

    list.add("one");
    list.add("two");
    list.add("three");
    list.add("four");

    // 注意Iterator 也是泛型.
    Iterator< String> itr = list.iterator();

    // Iterator< Integer> itr = list.iterator(); // 这样会产生编译错误!

    while(itr.hasNext()) {
      String str = itr.next(); // no cast needed

      // Now, the following line is a compile-time,
      // rather than runtime, error.
      // Integer i = itr.next(); // this won't compile

      System.out.println(str + " is " + str.length() + " chars long.");
    }
  } 
}

清单 19(擦拭)
// 这个类编译后,T将被Object替换掉.
class Gen< T> { 
  T ob; // here, T will be replaced by Object
   
  Gen(T o) { 
    ob = o; 
  } 
 
  // Return ob. 
  T getob() { 
    return ob; 
  } 


// 编译后.这个类中的T 将被String替换.
class GenStr< T extends String> {
  T str; // here, T will be replaced by String

  GenStr(T o) { 
    str = o; 
  } 

  T getstr() { return str; }
}

清单 20
class GenTypeDemo { 
  public  static void main(String args[]) { 
    Gen< Integer> iOb = new Gen< Integer>(99); 
    Gen< Float> fOb = new Gen< Float>(102.2F);

    System.out.println(iOb.getClass().getName());
    System.out.println(fOb.getClass().getName());
  }
}

运行的输出:(在编译时所有类型都被擦拭了,运行时,只有原始类型存在.)
Gen
Gen

分享到:
评论

相关推荐

    Java泛型&lt;T&gt; T与T的使用方法详解

    主要介绍了Java泛型&lt;T&gt; T与T的使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    详解c# 泛型类的功能

    在泛型类中,由于不知道泛型参数T是什么类型,可能是引用类型,也可能是值类型,因此不能将null等赋予泛型类型。... private readonly Queue&lt;T&gt; documentQueue = new Queue&lt;T&gt;(); public void AddDocume

    C#泛型Dictionary的用法实例详解

    本文以实例形式讲述了C#中的泛型Dictionary的用法。具有很好的实用价值。分享给大家供大家参考。具体如下: 泛型最常见的用途是泛型集合,...List&lt;T&gt; HashTable DIctionary&lt;T&gt; Queue Queue&lt;T&gt; Stack Stack&lt;

    详解FuncT与ActionT区别

    Func&lt;Result&gt;,Func&lt;T1&gt;是一个.Net内置的泛型委托。 Func&lt;TResult&gt; Func&lt;T&gt; Func&lt;T1&gt; Func&lt;T1&gt; Func&lt;T1&gt; 它有5种形式,只是参数个数不同;第一个是无参数,但是有返回值; 下面是一个简单的普通委托来传方法的示例...

    利用Distinct()内置方法对List集合的去重问题详解

    先来看看泛型链表 List&lt;T&gt; 的定义: public class List&lt;T&gt; : IList&lt;T&gt;, ICollection&lt;T&gt;, IList, ICollection, IReadOnlyList&lt;T&gt;, IReadOnlyCollection&lt;T&gt;, IEnumerable&lt;T&gt;, IEnumerable 可见它实

    C#实现类型的比较示例详解

    IComparable&lt;T&gt; .NET 里,IComparable&lt;T&gt;是用来作比较的最常用接口。 如果某个类型的实例需要与该类型的其它实例进行比较或者排序的话,那么该类型就可以通过实现IComparable&lt;T&gt;接口来达到此目的。 IComparable&lt;T&gt;只...

    JAVA泛型总结

    class Point&lt;T&gt; class Notepad&lt;K,V&gt;{ // 此处指定了两个泛型类型 } 通配符、受限泛型、泛型无法向上转型、泛型接口、泛型方法、通过泛型方法返回泛型类型实例、使用泛型统一传入的参数类型、泛型数组、泛型的嵌套...

    c# 自定义泛型链表类的详解

    代码如下:public class GenericList&lt;T&gt; { private class Node { //当前节点值 private T data; public T Data { get { return data; } set { data = value; } } //节点的下一个节点 private Nod

    C# ArrayList、HashSet、HashTable、List、Dictionary的区别详解

    在C#中,数组由于是固定长度的,所以常常不能满足我们开发的需求。 由于这种限制不方便,所以出现了ArrayList。 ArrayList、List&lt;T&gt; ArrayList是可变长数组,你可以将任意多的数据Add到...List&lt;T&gt;是ArrayList的泛型

    详解如何选择使用ArrayList、HashTable、List、Dictionary数组

    在C#中,数组由于是固定长度的,所以常常不能满足我们开发的需求。 由于这种限制不方便,所以出现了ArrayList。 ArrayList、List&lt;T&gt; ArrayList是可变长数组,你可以将任意多的数据Add到...List&lt;T&gt;是ArrayList的泛型版

    详解C#中的泛型以及编程中使用泛型的优点

    2.0 版 C# 语言和公共语言运行时 (CLR) 中增加了泛型。泛型将类型参数的概念引入 .NET Framework,类型参数使得设计如下类和方法...public class GenericList&lt;T&gt; { void Add(T input) { } } class TestGenericList {

    C#读取数据库返回泛型集合详解(DataSetToList)

    本篇文章主要是对C#读取数据库返回泛型集合(DataSetToList)进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助

    C#泛型方法在lua中表示的一种设计详解

    前言 在进行lua方法注册的时候, 大多数解决方案直接否定了泛型方法, 因为在lua侧难以表达出泛型, 以及lua的函数重载问题, 函数重载问题可以通过一些特殊... public static void GetTypeName&lt;T&gt;() { Debug.Log(typeof

    解析从源码分析常见的基于Array的数据结构动态扩容机制的详解

    本文的写作冲动来源于今晚看到的老赵的一则微博“大家知道System.Collections.Generic.List&lt;T&gt;是一种什么样的数据结构?内部的元素是怎么存放的?还有Dictionary&lt;TKey&gt;呢?…”。 查了一下书,如果参考数据结构和...

    Kotlin中协变、逆变和不变示例详解

    super T&gt; 通配符型变约束,而是采用类似 C# 的 in,out 用于支持协变和逆变,这同时避免了处理子类型化,父类化的问题(即Java泛型中典型的List&lt;T&gt; 不是 List&lt;Object&gt;的子类型的问题); 基本的泛型语法可以...

    一看就懂 详解JAVA泛型通配符T,E,K,V区别

    泛型从字面上理解,是指一个类、接口或方法支持多种类型,使之广泛化、一般化和更加通用。通配符只有在修饰一个变量时会用到,使用它可方便地引用包含了多种类型的泛型;下面我们来深入了解一下吧

    详解:泛型、擦除、边界

    为何有了接口,我们还需要使用泛型?...使用泛型参数 T,用尖括号括住,放在类后。 /** * 使用泛型参数 T,用尖括号括住,放在类后 */ public class Tested { private T t; public void set(T t) { this.t = t;

    C#中可枚举类型详解

    枚举是迭代一个集合中的数据项的过程。 我们经常使用的大多数集合实际上...所以一切的集合和数组都可以用IEnumerable或者IEnumerable&lt;T&gt;接口来定义。 IEnumerable lists1 = new int[] { 3, 4, 5 }; foreach(var val

    详解C#泛型的类型参数约束

    where T : struct 类型参数必须是不可为 null 的值类型。 有关可为 null 的值类型的信息,请参阅可为 null 的值类型。 由于所有值类型都具有可访问的无参数构造函数,因此 struct 约束表示 new() 约束,并且不能与

    《C++String深入详解2.0版》PDF

    2.1.4 以char和wchar_t特化char_traits 56 附录3:Boost.Format中文文档 57 2.1 大纲 57 2.2 它是如何工作的 57 2.3语法 58 2.3.1 boost::format( format-string ) % arg1 % arg2 % ... % argN 58 2.3.2 printf 格式...

Global site tag (gtag.js) - Google Analytics