Java中泛型的基础到提高《精简》

<span style="font-family: SimHei; background-color: rgb(255, 255, 255);"> </span><span style="font-family: SimHei; background-color: rgb(255, 255, 255);"></span><span style="font-family:SimHei;font-size:24px;color:#ff0000;">泛型初级</span><span style="font-family: SimHei; background-color: rgb(255, 255, 255); font-size: 18px;"><span style="white-space:pre"></span>泛型的由来:</span>

集合中可以存储任意类型对象,但是在取出时,如果要使用具体对象的特有方法时,

需要进行向下转型,如果存储的对象类型不一致,在转型过程中就会出现ClassCastException异常。

这样就给程序带来了不安全性。在jdk1.5以后就有了解决方案——泛型技术:在存储元素时,就不允许存储不同类型的元素。

存储了就编译失败。 所以就需要在存储元素时,在容器上明确具体的元素类型,这其实和数组定义很像。

泛型的好处:

1)将运行时期的ClassCastException异常转移到了编译时期,进行检查,并以编译失败来体现。 这样有利于程序员尽早解决问题。(不会再运行中出现异常,在编译时候就能够发现错误)(泛型规定不能只能是自己的类型或者是子类)2)避免了向下转型(强转)的麻烦。

代码说明一切:

package cn.hncu.generic;//泛型能够限制类型。public class genericdemo1 {public static void main(String[] args) {Mygeneric<Worker> generic =new Mygeneric<Worker>();generic.add(new Worker());//generic.add(00); 自己定义了泛型,只能是Worker类型的//generic.add(new Student());//同样的报错,只能添加相同类型的数据System.out.println(generic);Mygeneric<Student> s=new Mygeneric<Student>();s.add(new Student());//s.add(new Worker());//编译通不过,出错,只能添加泛型定义的数据}}class Mygeneric <QQ>{//自己定义泛型,随便写写,最重要的是<>里面的内容必须与下面的一致,内容随便写都可以QQ obj;public void add(QQ obj){//由于前面限制,所以只能添加QQ类型的数据System.out.println("add:"+obj);}public QQ out(){return obj;}@Overridepublic String toString() {return "Mygeneric [obj=" + obj + "]";}}class Worker{}class Student{}

使用泛型的动机举例(以集合为例):

对集合中存放元素的类型进行限定,防止后期出错。如果限定某个集合只能存放Person类对象(因为后期会把元素取出来当作Person对象来处理),这样放其它类型的对象在编译时就会报错。相当于把一个类泛化成很多个不同类型(具体化,限定化)的类。泛型使用的代码如:

List<Person> persons = new ArrayList<Person>;Map<String,String> m = new HashMap<String,String>;

注意:当一个变量被声明为泛型时,只能被实例变量和方法调用,而不能被静态变量和方法调用。原因很简单,参数化的泛型是一些实例。静态成员是被类的实例和参数化的类所共享的,所以静态成员不应该有类型参数和他们关联。 当一个类要操作的引用数据类型不确定的时候,可以将该类型定义一个形参。用到的这类时,由使用者来通过传递类型参数的形式,来确定要操作的具体的对象类型。什么时候使用泛型类呢?只要类中操作的引用数据类型不确定的时候,就可以定义泛型类。 有了泛型类,省去了曾经的强转和类型转换异常的麻烦。

部分代码:

class Mygen<E>{public void add(E e){System.out.println(e.toString());}public Object out(Object obj){//方法不带泛型,当返回时候需要强转,,不是很安全return obj;}public <A> A myout(A a){//方法带泛型,但要求和类的泛型相互独立。可以限定返回类型和方法的实参相同,更安全,而且不用强转。System.out.println("myout:" +a);return a;}////静态方法带泛型,泛型一定要独立于类,因为它没有对象。public static <E> E myout1(E a){System.out.println("myout:" +a);return a;}

完整简单代码演示《细节都在代码解释中》:

package cn.hncu.generic;public class genericdemo2 {public static void main(String[] args) {Mygen<String > my =new Mygen<String>();my.add("abc");//my.add(21);//编译错误,泛型规定只能使用String类型的String s=(String) my.out("asd");//方法不带泛型,返回值需要强转,不是很安全//返回值也必须是泛型类型; 泛型很安全//方法带泛型,但要求和类的泛型相互独立。可以限定返回类型和方法的实参相同,更安全,而且不用强转。 int m=my.myout(11);//myout:11;返回值和传进去的参数类型必须一致;char c=my.myout1('a');}}class Mygen<E>{public void add(E e){System.out.println(e.toString());}public Object out(Object obj){//方法不带泛型,当返回时候需要强转,不是很安全return obj;}public <A> A myout(A a){//方法带泛型,但要求和类的泛型相互独立。可以限定返回类型和方法的实参相同,更安全,而且不用强转。System.out.println("myout:" +a);return a;}////静态方法带泛型,泛型一定要独立于类,因为它没有对象。public static <E> E myout1(E a){System.out.println("myout:" +a);return a;}}当某些类用的接口泛型时候,我们也能解决,要求返回和类一样和不一样的类型的泛型都能解决,详见线面代码:package cn.hncu.generic;public class genericdemo2 {public static void main(String[] args) {Mygen<String > my =new Mygen<String>();my.add("abc");//my.add(21);//编译错误,泛型规定只能使用String类型的String s=(String) my.out("asd");//方法不带泛型,返回值需要强转,不是很安全//返回值也必须是泛型类型; 泛型很安全//方法带泛型,但要求和类的泛型相互独立。可以限定返回类型和方法的实参相同,更安全,而且不用强转。 int m=my.myout(11);//myout:11;返回值和传进去的参数类型必须一致;char c=my.myout1('a');}}class Mygen<E>{public void add(E e){System.out.println(e.toString());}public Object out(Object obj){//方法不带泛型,当返回时候需要强转,不是很安全return obj;}public <A> A myout(A a){//方法带泛型,但要求和类的泛型相互独立。可以限定返回类型和方法的实参相同,更安全,而且不用强转。System.out.println("myout:" +a);return a;}////静态方法带泛型,泛型一定要独立于类,因为它没有对象。public static <E> E myout1(E a){System.out.println("myout:" +a);return a;}}

泛型高级:

泛型的通配符:?

当操作的不同容器中的类型都不确定的时候,而且使用的都是元素从Object类中继承的方法,

这时泛型就用通配符?来表示即可。(助理解的比方: 泛型中的多态应用)。

人生就像是一场旅行,遇到的既有感人的,

Java中泛型的基础到提高《精简》

相关文章:

你感兴趣的文章:

标签云: