泛型

原创 2008年09月30日 00:55:00
泛型
一、什么是泛型?
通过泛型可以定义类型安全类,而不会损害类型安全、性能或工作效率

二、实例化泛型
1、可以使用任何类型来声明和实例化
2、申明和实例话都必须用一个特定的类型来代替一般类型T
3、例子:
//原来写法
Public   class   Stack
{
object[]   m_Items;
public   void   Push(object   item)
{...}
public   object   Pop()
{...}
}
Stack   stack   =   new   Stack();
stack.Push(1);
int   number   =   (int)stack.Pop();

//有了泛型后
Public   class   Stack <T>
{
T[]   m_Items;
public   void   Push(T   item)
{...}
public   T   Pop()
{...}
}
Stack <int>   stack   =   new   Stack <int> ();
stack.Push(1);
int   number   =   (int)stack.Pop();

三:泛型的好处
1、一次性的开发、测试和部署代码,通过任何类型来重用它
2、编译器支持和类型安全
3、不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。
注:值类型大概可以提高200%,引用类型大概为100%

四:多个泛型
1、单个类型可以定义多个泛型

五:泛型别名
1、在文件头部使用using   为特定类型取别名,别名作用范围是整个文件
2、例子
using   List   =   LinkedList <int,string> ;
class   ListClient
{
static   void   Main(string[]   args)
{
List   list   =   new   List();
list.AddHead(123, "AAA ");
}
}

五:泛型约束
(1)、派生约束
如:
public   class   LinkedList <K,T>   where   K:IComparable
{
T   Find(K   key)
{
if   (str.Key.CompareTo(key)   ==   0)//只有实现这个接口才可比较
}
}

注意:
1、所有的派生约束必须放在类的实际派生列表之后
如:public   class   LinkedList <K,T> :IEnumerable <T>   where   K:IComparable <K>
        {...}
2、一个泛型参数上可以约束多个接口(用逗号分隔)
public   class   LinkedList <K,T>   where   K:IComparable <K> ,IConvertible
3、在一个约束中最多只能使用一个基类
4、约束的基类不能是密封类或静态类
5、不能将System.Delegate或System.Array约束为基类
6、可以同时约束一个基类以及一个或多个接口,但是该基类必须首先出现在派生约束列表中。
7、C#允许你将另一个泛型参数指定为约束
public   class   MyClass <T,U>   where   T:U
{...}
8、可以自己定义基类或接口进行泛型约束
9、自定义的接口或基类必须与泛型具有一致的可见性

(2)、构造函数约束
如:
class   Node   <K,T>   where   T:new()
{
}
注意:
1、可以将构造函数的约束和派生约束结合起来,前提是构造函数的约束出现在约束列表中的最后

(3)、引用/值类型约束
1、可以使用struct约束将泛型参数约束为值类型(如int、bool、enum),或任何自定义结构
2、同样可以使用class约束将泛型参数约束为引用类型
3、不能将引用/值类型约束与基类约束一起使用,因为基类约束涉及到类
4、不能使用结构和默认构造函数约束,因为默认构造函数约束也涉及到类
5、虽然您可以使用类和默认构造函数约束,但是这样做没有任何价值
6、可以将引用/值类型约束与接口约束组合起来,前提是引用/值类型约束出现在约束列表的开头

六:泛型和强制类型转换
1、C#编译器只允许将泛型参数隐式转换到Object或约束指定的类型
如:
interface   IS{...}
class   BaseClass{...}
class   MyClass <T>   where   T:BaseClass,IS
{
void   SomeMethod(T   t)
{
IS   obj1   =   t;
BaseClass   obj2   =   t;
object   obj3   =   t;
}
}
2、编译器允许你将泛型参数显示强制转换到其他任何借口,但不能将其转换到类
interface   IS{...}
class   SomeClass{...}
class   MyClass   <T>   //没有约束
{
void   SomeMethod(T   t)
{
IS   obj1   =   (IS)t;   //可以
SomeClass   obj2   =   (SomeClass)t   //不可以
}
}
3、可以使用临时的Object变量,将泛型参数强制转换到其他任何类型
class   SomeClass{...}
class   MyClass   <T>  
{
void   SomeMethod(T   t)
{
object   temp   =   t;
SomeClass   obj   =   (SomeClass)temp;//可以
}
}
注意:这里只是告诉你这样写是可以的,但是要不要这样写?不要这样写,因为如果t确实没有继承SomeClass编译没错但是运行就会出错
4、解决上面强制转换问题,可以使用is和as运算符进行判断
public   class   MyClass <T>
{
public   void   SomeMethod <T   t>
{
if   (t   is   int   ){...}
if   (t   is   LinkedList <int,string> ){...}
//如果泛型参数的类型是所查询的类型,则is运算符返回true
string   str   =   t   as   string;
//如果这写类型兼容,则as将执行强制类型转换,否则将返回null
if   (str   !=   null){...}
LinkedList <int,string>   list   =   t   as   LinkedList <int,string> ;
if   (list   !=   null){...}
}
}

七:继承和泛型
1、在从泛型基类派生,可以提供类型实参,而不是基类泛型参数
public   class   BaseClass <T> {...}
public   class   SubClass:BaseClass <int>
2、如果子类是泛型,而非具体的类型实参,则可以使用子类泛型参数作为泛型基类的指定类型
public   class   BaseClass <TT> {...}
public   class   SubClass <T> :BaseClass <T> {...}
3、在使用子类泛型参数时,必须在子类级别重复在基类级别规定的任何约束
4、基类可以定义其签名使用泛型参数的虚礼方法,在重写它们时,子类必须在方法签名中提供相应的类型。
如:
public   class   BaseClass <T>
{
public   virtual   T   SomeMethod()
{...}
}
public   class   SubClass:BaseClass <int>
{
public   override   int   SomeMethod()
{...}
}
5、如果该子类是泛型,则它还可以在重写时使用它自己的泛型参数
public   class   SubClass <T> :BaseClass <T>
{
public   override   T   SomeMethod()
{...}
}
6、你可以定义泛型接口、泛型抽象类,甚至泛型抽象方法。
7、不能对泛型参数使用+或+=之类的运算符
public   class   Calculator <T>
{
public   T   Add   (T   arg1,T   arg2)
{
return   arg1   +   arg2;//错误
}
}
但是我们可以通过泛型抽象类、接口来实现在个功能,因为实现泛型抽象类、接口我们就已经明确传一个参数了,就可以执行诸如+这样的操作。

八:泛型方法
1、方法可以定义特定于其执行范围的泛型参数
public   class   MyClass <T>
{
public   void   MyMethod <X> (X   x)
{...}
}
2、即使各包含类根本不使用泛型,你也可以定义方法特定的泛型参数
public   class   MyClass
{
public   void   MyMethod <T> (T   t)
{...}
}
注意:该功能只使用于方法,属性,索引器只能使用在类的作用范围中定义的泛型参数。
3、调用泛型方法
MyClass   obj   =   new   MyClass();
obj.MyMethod <int> (3);
也可以这样:
MyClass   obj   =   new   MyClass();
obj.MyMethod(3);   //该功能称为泛型推理
4、泛型方法也可以有自己的泛型参数约束
pubic   class   MyClass
{
public   void   SomeMethod <T> (T   t)   where   T:IComparable <T>
{...}
}
5、子类方法实现不能重复在父级别出现的约束
public   class   BaseClass
{
public   virtual   void   SomeMethod <T> (T   t)where   T:new()
{...}
}
pubic   class   SubClass:BaseClass
{
public   override   void   SomeMethod <T> (T   t)//不能再有约束
{...}
}
6、静态方法
静态方法可以定义特定的泛型参数和约束
public   class   MyClass <T>
{
public   static   T   SomeMethod <X> (T   t,X   x)
{...}
}
int   number   =   MyClass <int> .SomeMethod <string> (3, "AAA ");
或者:int   mumber   =   MyClass <int> .SomeMethod(3, "AAA ");

九:泛型委托
1、在某个类中定义的委托可以利用该类的泛型参数
2、委托也可以定义自己的泛型参数

2. Java面向对象之泛型-构造方法中使用

package generic; class Construtgeneric { private T value; public Construtgeneric(T value)...
  • i10630226
  • i10630226
  • 2015年07月28日 20:59
  • 1884

java泛型对象初始化--java泛型对象能实例化吗T t=new T()

java中没法得到泛型参数化类型,因为在编译期没法确定泛型参数化类型,也就找不到对应的类字节码文件,自然就不行了  泛型反射的关键是获取ParameterizedType,再调用它的getActual...
  • q383965374
  • q383965374
  • 2014年07月01日 19:08
  • 20507

简单的关于java的伪泛型的一个小例子

Java的泛型,不同于c#的泛型,    c#中的泛型无论在程序的源码中,编译后的IL中,还是在运行前的CLR中都切实存在的, List与List就是两个不同的类型,它们在运行期生成, 有自己的虚方法...
  • u013135520
  • u013135520
  • 2017年01月02日 23:13
  • 451

应用泛型的策略模式

应用泛型的策略模式作者:Dr. Heinz M. Kabutz   摘要策略模式相当的简单。通过使用这个模式,我们可以把一些内聚的状态转化为一些外在的状态,这样可以实现共享策略对象。当每一个策略对象为...
  • hivon
  • hivon
  • 2006年04月16日 10:25
  • 3685

泛型&泛型的通配符使用

泛型   package itheima.com.GenericEx; import java.lang.reflect.InvocationTargetException; import j...
  • yaomqiao
  • yaomqiao
  • 2014年05月15日 10:27
  • 642

泛型继承的几种写法

泛型 继承
  • ShierJun
  • ShierJun
  • 2016年04月26日 20:41
  • 9416

Java返回泛型的方法-实例

package com.frank.app; import java.io.UnsupportedEncodingException; import java.lang.reflect.Type; ...
  • lsm135
  • lsm135
  • 2017年01月06日 18:37
  • 789

开发积累—泛型工具类

前言:使用SSH2中使用的泛型工具类,以前写泛型比较麻烦。今天收集到一个工具类,好东呀!!分享给大家,绝对有用。JAVA版的web应用程序使用。...
  • u011331844
  • u011331844
  • 2014年05月19日 22:40
  • 1489

Google Guava-基于泛型的使用方式

源码: private static Cache cacheFormCallable = null; public static Cache callableCached() throws Ex...
  • u012516914
  • u012516914
  • 2015年02月04日 11:41
  • 1017

JAVA 泛型练习

二分查找: public class Q212 { public static void main(String [] args) { Integer []arr = {1,2,3,4,5,6...
  • k183000860
  • k183000860
  • 2015年03月09日 10:14
  • 543
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:泛型
举报原因:
原因补充:

(最多只允许输入30个字)