添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
private T t =new T(); private T[] tArray=new T[5]; private List list= new ArrayList();

这段代码有什么问题呢? t、tArray、list都是类变量,都是通过new声明了一个类型, 看起来非常相似啊!但这段代码是编译通不过的,因为编译器在编译时需要获得T类型,但 泛型在编译期类型已经被擦除了,所以new T()和new T[5]都会报错(可能有读者疑惑了 : 泛型类型可以擦除为顶级类Object,那T类型擦除成Object不就可以编译了吗?这样也不 行,泛型只是Java语言的一部分,Java语言毕竟是一个强类型、编译型的安全语言,要确保运行期的稳定性和安全性就必须要求在编译器上严格检査)。可为什么new Arr a yList<T>()却 不会报错呢?

这是因为ArrayList表面是泛型,其实已经在编译期转型为Object 了,我们来看一下 ArrayList的源代码就清楚了,代码如下:

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
   //容纳元素的数组
   private transient Object[] elementData;
    //构造函数
    public ArrayList() { 
       this(10);
   //获得一个元素
   public E get(int index) {
    RangeChecM (index);
  //返回前强制类型转换
    return (E) elementData[index];
注意elementData的定义,它容纳了 ArrayList的所有元素,其类型是Object数组,因为Object是所有类的父类,_数组又允许协变(Covariant),因此elementData数组可以容 纳所有的实例对象。元素加入时向上转型为Object类型(E类型转为Object),取出时向下 转型为E类型(Object转为E类型),如此处理而已。 

在某些情况下,我们确实需要泛型数组,那该如何处理呢?代码如下:

 private T t;
  private T[] tArray;
  private List<T> list=new ArrayList<T>();
  public Foo() {
	try {
		Class<?> tType=Class.forName("");
		t=(T) tType.newInstance();
		tArray=(T[]) Array.newInstance(tType, 5);
	} catch (Exception e) {
		e.printStackTrace();

此时,运行就没有任何问题了。剩下的问题就是怎么在运行期获得T的类型,也就是 tType参数,一般情况下泛型类型是无法获取的,不过,在客户端调用时多传输一个T类型 的class就会解决问题。

类的成员变量是在类初始化前初始化的,所以要求在初始化前它必须具有明确的类型, 否则就只能声明,不能初始化。

泛型类型在编译期被擦除,我们在类初始化时将无法获得泛型的具体参数,比如这样的代码:class Foo{ private T t =new T(); private T[] tArray=new T[5]; private List list= new ArrayList();}这段代码有什么问题呢? t、tArray、list都是类变量,都是通过new声明了一个类型, 看起来非常
C# 数组在 C# 2.0 中,下限为零的一维数组自动实现 IList。这使您可以创建能够使用相同代码循环访问数组和其他集合类方法。此技术主要对读取集合中的数据很有用。IList 接口不能用于在数组中添加或移除元素;如果试图在此上下文中调用 IList 方法(如数组的 RemoveAt),将引发异常。下面的代码示例演示带有 IList 输入参数的单个方法如何同时循环访问列表和数组,本例中为整数数组。 C# 数组代码 代码如下: class Program { static void Main() { int[] arr = { 0, 1, 2,
什么是(Generic type 或者 generics)是对 Java 语言的类系统的一种扩展,以支持创建可以按类进行参数化的类。可以把类参数看作是使用参数化类时指定的类的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。 可以在集合框架(Collection framework)中看到的动机。例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类(比如 String)的对象。 因为 Map.get() 被
数组初始化问题 这个用法是在自己写动态数组的时候遇到的问题,需要在构造器中创建初始化数组,但是因为不能直接创建,所以需要先创建一个Object对象,再强制转换类,这个做法其实不太好,这里又涉及到了向上转和向下转的问题。这个不知道ArrayList是怎么做的,后面补上。 array = (T[]) new Object[size]; 二 向上转和向下转 参考次链接 2.声明数组 通用格式: TypeName ArrayName[ArraySize]; (1)TypeName :存储在数组中每个元素的值得类,比如:int、 float 、double、char等。 (2)ArrayName :数组名。 (3)Arr..
每种类的变量都有各自的初始化方法,memset() 函数可以说是初始化内存的“万能函数”,通常为新申请的内存进行初始化工作。它是直接操作内存空间,mem即“内存”(memory)的意思。该函数的原为 # include <string.h> void *memset(void *s, int c, unsigned long n); 函数的功能是:将指针变量 s 所指向的前 n 字节的内存单元用一个“整数” c 替换,注意 c 是 int 。s 是 void* 的指针变量,所以它可以为
属性是指属性的类,可以使用类参数来表示。在初始化属性时,需要在属性的类后面加上类参数,表示该属性的具体类。例如,定义一个属性List<T>,其中T是类参数,表示List的元素类,那么初始化该属性时就需要指定T的具体类,例如List<String>或List<Integer>等。 在C#中,可以使用属性初始化器来初始化属性。例如,定义一个类,其中有一个属性List<T>,并在属性初始化器中初始化该属性: class MyClass public List<string> MyList { get; set; } = new List<string>(); 在上面的代码中,MyList是一个属性,类为List<string>,在属性初始化器中使用new关键字初始化了该属性,使其成为一个空的字符串列表。这样,在创建MyClass类的实例时,MyList属性就已经被初始化了。