A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 占琳 中级黑马   /  2012-11-3 18:39  /  2174 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 占琳 于 2012-11-5 15:25 编辑

什么是泛型?何种情况下用泛型?

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

6 个回复

倒序浏览
泛型是jdk1.5版本出现的新特性,是一种类型安全机制,它将集合中的错误从运行期转换到了编译期
数组中的元素类型要求一致 而集合中可以添加不同类型的元素,但是这样出现了安全隐患
因此也必须要求集合中的元素类型唯一 因此 泛型就出现了 它规定集合中的元素必须和加泛型的定义类型一致
这样大大提高了集合的安全性
如:List<Person> list=new ArrayList<Person>();
list集合中的元素 只能是 Person对象

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
本帖最后由 李靖 于 2012-11-3 20:47 编辑

在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
1、泛型的类型参数只能是类类型(包括自定义类),不能是简单类型(就是说的基本类型,必须是Object的子类)。
2、同一种泛型可以对应多个版本(因为参数类型是不确定的),不同版本的泛型类实例是不兼容的。
3、泛型的类型参数可以有多个。
4、泛型的参数类型可以使用extends语句,例如<T extends superclass>。习惯上称为“下界类型”或 <T super Number>,上界类型,T是Number的父类或Number类。
5、泛型的参数类型还可以是通配符类型。例如Class<?> classType = Class.forName("java.lang.String");
泛型的去参数化是在编译成字节码的时候去掉的,所以不同的泛型参数,不能说是重载。因为泛型可以防止数据的挡住编译错误。如果想实现对Integer泛型实现对String类型数据的加入,必须通过反射机制来实现。

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
问的这么没水准 我都不好意思去复制了.

http://baike.baidu.com/view/965887.htm

摆渡百科直接有的问题就不要拿出来了吧 太丢人了
回复 使用道具 举报
所谓泛型是指将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。
一种类型占位符,或称之为类型参数。我们知道一个方法中,一个变量的值可以作为参数,但其实这个变量的类型本身也可以作为参数。泛型允许我们在调用的时候再指定这个类型参数是什么。在.net中,泛型能够给我们带来的两个明显好处是——类型安全和减少装箱、拆箱。
  例如:通常一个方法或过程的签名都是有明确的数据类型的。

  如 :

  public void ProcessData(int i){}

  public void ProcessData(string i){}

  public void ProcessData(decimal i){}

  public void ProcessData(double i){}

  等。

  这些方法的签名中的:int ,string,decimal,double 都是明确的数据类型,程序员访问这些方法的过程中需要提供提定类型的参数:

  ProcessData(123);

  ProcessData("abc");

  ProcessData("12.12")

  而如果我们将int ,string,decimal,double这些类型也当成一种参数传给方法的时候方法的定义便是这样:

  public void ProcessData<T>(T i){} //T是int ,string,decimal,double这些数据类型的指代

  用户在调用的时候便成了这样:

  ProcessData<string>("abc");

  ProcessData<int>(123);

  ProcessData<double>(12.23);

  这与通常的那些定义的最大区别是,方法的定义实现过程只有一个。但是它具有处理不同的数据类型数据的能力。

  C# 2.0中有如List<>等泛型对象都具有此特性。

  具有泛型机制的软件开发平台及语言

  .Net 平台 2.0及以上版本

  JAVA 5及以上版本

  泛型的好处:

  泛型是c#2.0的一个新增加的特性,它为使用c#语言编写面向对象程序增加了极大的效力和灵活性。它允许程序员将一个实际的数据类型的规约延迟至泛型的实例被创建时才确定。泛型为开发者提供了一种高性能的编程方式,能够提高代码的重用性,并允许开发者编写非常优雅的解决方案。


数据层:

public List<libs.Model.Artitle> GetAllArt()
{
List<libs.Model.Artitle> list = new List<Artitle>();

string sqlconn = System.Configuration.ConfigurationSettings.AppSettings["sqlconn"];
SqlConnection conn = new SqlConnection(sqlconn);
string sqlstr = "select titleid,Title,author,company,Uploaddate,isVidate,conimages,content from writings order by titleid asc";
SqlCommand cmd = new SqlCommand (sqlstr,conn);

try
{
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
libs.Model.Artitle artles = new Artitle();
artles.Titleid = int.Parse(reader["titleid"].ToString());
artles.Title = reader["title"].ToString();
artles.Uploaddate = DateTime.Parse(reader["Uploaddate"].ToString());
list.Add(artles);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
finally
{
conn.Close();
}
return list;

}

逻辑层:

public List<Artitle> GettitleAll()
{
return new libs.DAL.ArtileAccess().GetAllArt();
}

web层调用:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.GetallArt();

}
}

public void GetallArt()
{
libs.Log.Artitless atrlesst = new libs.Log.Artitless();
this.Repeater1.DataSource = atrlesst.GettitleAll(); //或者直接调用数据库层:

//this.Repeater1.DataSource = new libs.DAL.ArtileAccess().GetAllArt();
this.Repeater1.DataBind();
}



泛型较为广泛地被讨论,这里写到的只是作为新手的入门级认识。

泛型最常应用于集合类。

泛型的一个显而易见的优点在于可以在许多操作中避免强制转换或装箱操作的成本或风险,拿ArrayList这个集合类来说,为了达到其通用性,集合元素都将向上转换为object类型,对于值类型,更是有装箱拆箱的成本:

static void Main(string[] args)

{

ArrayList al = new ArrayList();

al.Add(1);

}

在IL中是:

IL_0008: ldc.i4.1

IL_0009: box [mscorlib]System.Int32

IL_000e: callvirt instance int32 [mscorlib]System.Collections.ArrayList::Add(object)

box操作就是装箱,具体过程是把值类型从栈中弹出,放入堆中,同时把在堆中的地址压入到栈中,频繁出现这样的操作,成本比较大。


所以在2.0中,遇到以上的应用,应该使用泛型集合类List<T>:

static void Main(string[] args)

{

List<int> l = new List<int>();

l.Add(1);

}


另一个比较常用的泛型集合类是Dictionary<T,T>,用于保存键值对:

static void Main(string[] args)

{

Dictionary<int, string> dict = new Dictionary<int, string>();

dict.Add(1, "SomeBook1");

dict.Add(2, "SomeBook2");

dict.Add(3, "SomeBook3");


Console.WriteLine(dict[2]);//output:SomeBook2

dict[2] = "SomeCD1";//modify

Console.WriteLine(dict[2]);//output:SomeCD1


dict.Remove(2);//delete


foreach (KeyValuePair<int, string> kv in dict)

{

Console.WriteLine("Key = {0}, Value = {1}",kv.Key, kv.Value);

}

}

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
qwepoidjdj 发表于 2012-11-3 20:44
问的这么没水准 我都不好意思去复制了.

http://baike.baidu.com/view/965887.htm

你觉得这些问题很简单?那么你不百度的情况下能不能完整的说出来呢?
不要忽视基础!否则以后你会乖乖的从头又去把那些你曾经忽略的知识捡回来的!
回复 使用道具 举报
本帖最后由 杨志男 于 2012-11-4 10:43 编辑

我的理解就是泛型就是固定容器中数据类型的,只在编译期有效。它的好处有两点:
第一,将原本在运行时期才出现的ClassCastException转移至编译时期,让程序员发现并解决问题
第二,避免强制转换的麻烦(以自定义比较器为例)
  1. //不使用泛型的情况
  2. class myComparator implements Comparator{
  3.         public int compare(Object o1,Object o2) {
  4.                 String str1=(String)o1;
  5.                 String str2=(String)o2;
  6.                 int num=new Integer(str1.length()).compareTo(new Integer(str2.length()));
  7.                 if (num==0)
  8.                         return str1.compareTo(str2);
  9.                 return num;
  10.         }
  11. }
复制代码
  1. //使用泛型的情况
  2. class myComparator implements Comparator<String>{
  3.         public int compare(String str1,String str2) {
  4.                 //String str1=(String)o1;
  5.                 //String str2=(String)o2;
  6.                 int num=new Integer(str1.length()).compareTo(new Integer(str2.length()));
  7.                 if (num==0)
  8.                         return str1.compareTo(str2);
  9.                 return num;
  10.         }
  11. }
复制代码
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马