黑马程序员技术交流社区

标题: java泛型 [打印本页]

作者: wyy283    时间: 2013-7-25 11:35
标题: java泛型
本帖最后由 杨兴庭 于 2013-7-25 23:14 编辑

一直不知道java泛型是干嘛的,谁能帮我解释下?另外有没有应用泛型的实际例子?谢谢了

作者: 王靖远    时间: 2013-7-25 11:47
泛型可以把运行期的类型转换安全隐患问题提前到编译期解决
作者: 王峰230321    时间: 2013-7-25 11:51
泛型是安全方面的新功能机制
格式:ArrayList<String> a1 = new ArrayList<String>();
<>用来接收类型,当使用集合时,将集合中存储的数据类型作为参数传递给集合
1泛型机制让运行时期报错转移到了编译时期
2避免了强制转换的麻烦
泛型类.泛型方法.,也可以在泛型类上定义泛型方法
静态方法不可以访问类上定义的泛型,因为泛型是在创建对象时才确定.但是可以在静态方法上定义新的泛型方法.
泛型同样也可以定义在接口上.<T>
当不确定类型的时候 可以用<?>
泛型也有效的简写了比较器功能


泛型的具体应用很广泛.  毕老师也是花了一整天的时间来讲. 所以 如果一点都不懂 还是 好好看看视频吧.  
作者: 付龙    时间: 2013-7-25 12:10
其实Java的泛型就是创建一个用类型作为参数的类。就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1、str2的值是可变的。而泛型也是一样的,这样写class Java_Generics<K,V>,这里边的K和V就象方法中的参数str1和str2,也是可变。

import Java.util.Hashtable;
class TestGen0<K,V>{
public Hashtable<K,V> h=new Hashtable<K,V>();
public void put(K k, V v) {
h.put(k,v);

public V get(K k) {
return h.get(k);

public static void main(String args[]){
TestGen0<String,String> t=new TestGen0<String,String>();
t.put("key", "value");
String s=t.get("key");
System.out.println(s);


正确输出:value

这只是个例子(Java中集合框架都泛型化了,这里费了2遍事.),不过看看是不是创建一个用类型作为参数的类,参数是K,V,传入的“值”是String类型。这个类他没有特定的待处理型别,以前我们定义好了一个类,在输入输入参数有所固定,是什么型别的有要求,但是现在编写程序,完全可以不制定参数的类型,具体用的时候来确定,增加了程序的通用性,像是一个模板。
作者: HM代景康    时间: 2013-7-25 13:48
泛型(Generic type 或者 generics)是对 Java 语言的类型系统的一种扩展,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。

可以在集合框架(Collection framework)中看到泛型的动机。例如,Map 类允许您向一个 Map 添加任意类的对象,即使最常见的情况是在给定映射(map)中保存某个特定类型(比如 String)的对象。

因为 Map.get() 被定义为返回 Object,所以一般必须将 Map.get() 的结果强制类型转换为期望的类型,如下面的代码所示:

Map m = new HashMap();
m.put("key", "blarg");
String s = (String) m.get("key");

要让程序通过编译,必须将 get() 的结果强制类型转换为 String,并且希望结果真的是一个 String。但是有可能某人已经在该映射中保存了不是 String 的东西,这样的话,上面的代码将会抛出 ClassCastException。

理想情况下,您可能会得出这样一个观点,即 m 是一个 Map,它将 String 键映射到 String 值。这可以让您消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。这就是泛型所做的工作。
作者: jialihong    时间: 2013-7-25 13:58
jdk1.5以前的集合类中存在什么问题?
ArrayList collection = new ArrayList();
  collection.add(1);
  collection.add(1L);
  collection.add("abc");
int i = (Integer)arrayList.get(1);//编译要强制类型转换且运行时出错
jdk1.5的集合类希望你在定义集合时,明确表示你要向集合中装哪种类型的数据,无法加入指定类型以外的数据
ArrayList<Integer> collection2 = new ArrayList<Integer>();
collection2.add(1);
/*
collection2.add(1L);
collection2.add("abc");
*///这两行代码编译时就报告了语法错误
int i2 = collection2.get(0);//不需要再进行类型转换
没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中,使用泛型集合,可以将一个集合中的元素限定为一个特定类型集合中只能存储同一个类型的对象,这样更安全,并且当从集合中获取一个对象时,编译器也可以知道这个对象的类型,不需要对对象进行强制类型转换,这样更方便。
泛型是提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率爱影响,对于参数化的泛型,getClass方法的返回值和原始类型完全一样。由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入类型的数据,例如:用反射得到集合,再调用add方法即可。
作者: liuzhming    时间: 2013-7-25 14:52
本帖最后由 liuzhming 于 2013-7-25 14:56 编辑

泛型之前,如果类别定义时的逻辑完全一样,只是里面成员变量的类型不同,需要定义多个类,这使得类的数量急剧膨胀。针对这种情况,设计了泛型。在定义类时,里面使用的类型不确定,而是让用户指定,这样减少了类定义的数量。举个例子,有两个这样的类:
public class IntegerFoo
{
        private Integer foo;

        public Integer getFoo()
        {
                return foo;
        }

        public void setFoo(Integer foo)
        {
                this.foo = foo;
        }
}

public class StringFoo
{
        private String foo;

        public String getFoo()
        {
                return foo;
        }

        public void setFoo(String foo)
        {
                this.foo = foo;
        }
}
这两个类里面实现逻辑完全相同,不同的仅仅是int和String类型,但却要定义两个。如果使用泛型,我们只需要定义一个类,如下:
public class Foo<T>
{
        private T foo;

        public T getFoo()
        {
                return foo;
        }

        public void setFoo(T foo)
        {
                this.foo = foo;
        }
}
Java里面使用了大量的泛型,最常见的是在集合里面,比如ArrayList,LinkedList,HashSet,MapSet等,还有迭代器iterator和ListIterator。例如在创建ArrayList对象时:ArrayList<String> ar = new ArrayList<String>。并且ArrayList<String>是一个确定的类,与ArrayList<int>是不同的类,两者没有关系。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2