Java学习笔记

泛型

2016-10-29  本文已影响74人  比轩

一、泛型技术的由来

泛型是从JDK 1.5开始出现的一种安全机制。之前的版本会有安全隐患出现,数据类型的问题,导致程序发生类型转换异常。所以,JDK 1.5开发出了泛型技术,解决程序中的安全问题。

二、泛型如何解决安全问题

泛型的出现,可以强制集合存储指定的数据类型,其它类型不允许存储。如果指定集合只能存储String,其他类型是存不进来的。

书写格式:通用格式 集合类<数据类型> 变量 = new 集合类<数据类型>();

三、泛型的好处

ArrayList<E> 源代码,E就是一个变量而已,在这个类的方法中,写了E,同一个变量。传递什么值,E就就是什么值,有点类似于C/C++的模板一样。

 ArrayList<String>  array =new ArrayList<String>();
//源代码中的E,就全部变成了,String

迭代器接口 Iterator<E>方法next()返回值也是E,如果迭代器中指定泛型是String类型,Iterator<String>.next()方法返回值,跟着变成了String类型

以后,如果你需要用一个类,发现类的右边写了一个尖括号<>写泛型了,指定具体的数据类型。当然,存储基本数据类型时,泛型需要写包装类。

基本数据类型 包装类
byte Byte
boolean Boolean
short Short
char Character
int Integer
long Long
float Float
double Double

四、泛型使用的demo

/*
 * 集合存储自定义对象,带泛型,迭代器获取
 * Person在之前的demo里面写过
 */
import java.util.*;
import cn.itcast.collection.Person;
public class GenericDemo1 {
    public static void main(String[] args) {
        //ArrayList存储Person
        ArrayList<Person> array = new ArrayList<Person>();
        array.add(new Person("a",10));
        array.add(new Person("b",11));
        array.add(new Person("c",12));
        
        //迭代器迭代集合,集合的泛型怎么写,迭代器跟随集合的泛型
        Iterator<Person> it = array.iterator();
        while(it.hasNext()){
            //it.next()返回值,就是泛型指定的Person,不用强转了
            Person p = it.next();
            System.out.println(p.getName()+"..."+p.getAge());
        }
    }
}

五、泛型类/方法/接口

1. 泛型类和方法

import java.util.ArrayList;
/*
 * 自定义泛型类,和泛型方法
 */

class Generic<QQ>{
    //使用类泛型
    public void show(QQ q){
        System.out.println(q);
    }
  
    //函数自定义泛型<>泛型修饰符在返回类型之前
    public <TT> void function(TT t){
        System.out.println(t);
    }
  
    //内部静态方法,静态不能调用非静态
    public  static <HAHA> void method(HAHA h){
        System.out.println(h);
    }
}
public class GenericDemo3 {
    public static  void main(String[] args) {
        Generic<Integer> g = new Generic<Integer>();
        //show方法的参数,跟随泛型走,现在的参数类型是Integer类型
        g.show(100);
        //调用方法function,泛型可以任意传递
        g.function('a');
        
      //静态方法,类名调用,使用方法自定义泛型,不跟随类 ,也不允许跟随类
        Generic.method("随便传");
    }
}

2. 泛型接口

接口上定义泛型:

demo:

/*
 * 自定义泛型接口,实现类实现接口,不指定泛型
 * 实现类实现接口的同时直接指定泛型
 */
interface Face<T>{
    public abstract void show(T t);
}

//定义实现类,实现接口,同时实现泛型
class FaceImpl2 implements Face<String>{
    public void show(String s ){
        System.out.println(s);
    }
}

//定义实现类,实现接口,不理会泛型,等待对象指定具体的数据类型
class FaceImpl<T> implements Face<T>{
    public void show(T t){
        System.out.println(t);
    }
}
public class GenericDemo4 {
    public static void main(String[] args) {
        FaceImpl<String> face = new FaceImpl<String>();
        FaceImpl<Integer> face1 = new FaceImpl<Integer>();
        face.show("随便传");
        
        FaceImpl2 face2 = new FaceImpl2();
        face2.show("只能是字符串");
    }
}

六、泛型的统配和限定

1. 泛型的通配符

传统文件系统中,通配符 * 匹配任意的文件名,或者是后缀名 del . del .java 等等。 假设定义方法,做集合的遍历,但是要求的是遍历任意的一个Collection下的子类集合,此时就要使用通配符。泛型中,通配符号?*问号,匹配所有的泛型类型,好处方便遍历集合,弊端在于不能进行强转。

demo

/*
 * 泛型的通配符
 */
import java.util.*;

public class GenericDemo1 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("asfd");
        list.add("adsfgsfd");
        list.add("sdfgsd");
        list.add("asertfd");
        list.add("qwey");
        method(list);
    }
    
    /*
     * 定义方法,遍历集合,但是不知道集合的类型
     * 使用  ? 泛型的通配符
     * 缺点:只能遍历。没办法做强转
     */
    public static void method(Collection<?> c){
        Iterator<?> it = c.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

2. 泛型的限定

泛型的限定问题,写泛型的时候,只需要确定子类,或者父类就可以使用泛型的限定,案例员工和经理,实现了限定操作,提高了安全性,避免了数据类型的强制转换

泛型上限限定 ? extends E 传递E类型 和E的子类

泛型下限限定 ? super E 传递E类型 和E的父类

七、增强for循环

直接给出demo:

package generic;

import java.util.*;

/*
 * 练习增强for循环
 */
public class ForeachDemo {
    public static void main(String[] args) {

        method2();
    }

    /*
     * 普通数据类型的遍历
     */
    public static void method() {
        int[] a = { 6, 8, 8, 9, 10, 674, 687 };

        for (int i : a) {
            System.out.print(i + "  ");
        }

        System.out.println("");
        char[] b = { 's', 'd', 'f', 'l', 'i' };

        for (char i : b) {
            System.out.print(i);
        }
    }

    /*
     * 对象数组的遍历
     */
    public static void method1() {
        String[] s = { "saefsadf", "saasdf", "sadfasdfsdf" };

        for (String i : s) {
            System.out.println(i.length());
        }
    }

    /*
     * 集合的遍历
     */
    public static void method2() {
        Set<String> s = new HashSet<String>();
        s.add("sretgd");
        s.add("dfga");
        s.add("sretwrey5gd");
        s.add("sresdfgrtgd");
        s.add("rt78uj");
        for (String i : s) {
            System.out.println(i.length());
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读