zoukankan      html  css  js  c++  java
  • Java学习笔记-泛型

    JDK1.5以后出现的机制,用以解决安全性问题

    泛型出现的原因

    泛型的特点

    • 提高了程序的安全性
    • 将运行期遇到的问题转移到了编译期
    • 省去了类型强转的麻烦
    • 泛型类的出现优化了程序设计

    泛型出现的好处

    • 将运行时期出现问题ClassCastException,转移到了编译时期,方便于程序员解决问题。让运行时问题减少,提高了安全性
    • 避免了强制转换麻烦

    泛型的书写格式

    泛型格式:
    通过<>来定义要操作的引用数据类型
    e.g.
    ArrayList<String> al = new ArrayList<String>();
    Iterator<String> it = al.iterator();

    import java.util.*;
    /*
    按照字符串长度排序
    */
    class Test {
    	public static void main(String[] args) {
    		TreeSet<String> ts = new TreeSet<String>(new LenComparator());
    		ts.add("abcd");
    		ts.add("cc");
    		ts.add("cba");
    		ts.add("aaa");
    		ts.add("z");
    		Iterator<String> it = ts.iterator();
    		while(it.hasNext()) {
                String s = it.next();
    			System.out.println(it.next());
    		}
    	}
    }
    
    class LenComparator implements Comparator<String> {
    	public int compare(String o1,String o2) {
    		int num = new Integer(o1.length()).compareTo(new Integer(o2.length()));
    		if(num == 0)
    			return o1.compareTo(o2);
    		return num;
    	}
    }
    

    自定义泛型类

    早期定义Object来完成扩展
    泛型前做法:定义类的时候使用Object,使用的时候强转
    这样的这发存在问题:在使用的时候,类型转换异常在编译时后不会报错,在运行时候报错

    class Student{}.
    class Worker{}
    class Tool {
    	private Object obj;
    	public void setObject(Object obj) {
    		this.obj = obj;
    	}
    	public Object getObject() {
    		return obj;
    	}
    }
    
    class Test {
    	public static void main(String[] args) {
    		Tool t = new Tool();
    		t.setObject(new Student());
    		Worker w = (Worker)t.getObject(); //运行时报类型转换异常
    	}
    }
    

    现在定义泛型来完成扩展
    当类中要操作的引用数据类型不确定的时候,使用泛型
    此时如果出现类型转换异常,就会在编译时候报错

    class Student{}.
    class Worker{}
    class Utils<T> {
    	private T t;
    	public void setT(T t) {
    		this.t = t;
    	}
    	public T getT() {
    		return t;
    	}
    }
    
    class Test {
    	public static void main(String[] args) {
    		Utils<Worker> u = new Utils<Worker>();
    		u.setObject(new Student());
    		Worker w = u.getObject(); //编译时报类型转换异常
    	}
    }
    

    自定义泛型方法

    • 泛型类定义的泛型,在整个类中有效。如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了
    • 为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上
    • 静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上
    • 方法上的泛型说明放在返回值修饰符前面

    类上定义泛型:相同符号代表相同类型

    class Demo<T> {
    	public void show(T t){
    		System.out.println("show:"+t);
    	}
    }
    

    方法中定义泛型

    class Demo<T> {
    	public <T> void show(T t) {
    		System.out.println("show:" + t);
    	}
        public <Q> void print(Q q) {
    		System.out.println("print:" + q);
    	}
    }
    

    类和方法中可以同时定义

    class Demo<T> {
    	public void show(T t) {
    		System.out.println("show:" + t);
    	}
    	public <T> void print(T t)
    	{
    		System.out.println("print:" + t);
    	}
    }
    

    静态方法定义泛型

    class Demo<T> {
    	public void show(T t) {
    		System.out.println("show:" + t);
    	}
    	public <Q> void print(Q q) {
    		System.out.println("print:" + q);
    	}
    	public  static <W> void method(W w) {
    		System.out.println("method:" + w);
    	}
    }
    

    自定义泛型接口

    可以在接口子类中指明类型,也可以不指明

    interface Inter<T> {
    	void show(T t);
    }
    
    class InterImpl1 implements Inter<String> {
    	public void show(String t) {
    		System.out.println("show :" + t);
    	}
    }
    
    
    class InterImpl2<T> implements Inter<T> {
    	public void show(T t) {
    		System.out.println("show :" + t);
    	}
    }
    class Test {
    	public static void main(String[] args) {
            InterImpl1 i1 = new InterImpl1();
    		i1.show("test");
    		InterImpl2<Integer> i2 = new InterImpl2<Integer>();
    		i2.show(0);
    	}
    }
    

    通配符(?)

    在泛型的使用中,有可能存在多种类型的使用,此时可以用<?>占位,代表接受任意类型
    使用<?>无法接收参数

    public static void printColl(ArrayList<?> al){
    	Iterator<?> it = al.iterator();
        while(it.hasNext()){
    		System.out.println(it.next());
    	}
    }
    

    使用<T>可以接收参数

    public static <T> void printColl(ArrayList<T> al){
    	Iterator<T> it = al.iterator();
        while(it.hasNext()){
            T t = it.next();
    		System.out.println(t);
    	}
    }
    

    泛型的限定:
    ? extends E: 可以接收E类型或者E的子类型。上限
    ? super E: 可以接收E类型或者E的父类型。下限

    import java.util.*;
    class Person {
    	private String name;
    	Person(String name) {
    		this.name = name;
    	}
    	public String getName() {
    		return name;
    	}
    }
    
    class Student extends Person {
    	Student(String name) {
    		super(name);
    	}
    }
    
    class  Test {
    	public static void main(String[] args) {
    
            ArrayList<Person> al = new ArrayList<Person>();
    		al.add(new Person("abc1"));
    		al.add(new Person("abc2"));
    		al.add(new Person("abc3"));
    		printColl(al);
    
    		ArrayList<Student> al1 = new ArrayList<Student>();
    		al1.add(new Student("abc--1"));
    		al1.add(new Student("abc--2"));
    		al1.add(new Student("abc--3"));
    		printColl(al1);
        }
    
        public static void printColl(Collection<? extends Person> al){ //接收Person及其子类
        	Iterator<? extends Person> it = al.iterator();
        	while(it.hasNext()) {
        		System.out.println(it.next().getName());
        	}
        }
    }
    
  • 相关阅读:
    数据持久化的复习
    iOS: 消息通信中的Notification&KVO
    iOS 证书与签名 解惑详解
    数据持久化 技术比较
    iOS开发拓展篇-XMPP简单介绍
    iOS block并发
    Xcode把应用程序打包成ipa
    谈谈用SQLite和FMDB而不用Core Data
    cannot use the same dataset for report.dataset and page.dataset
    cxGRID中的字段怎么能以0.00的格式显示
  • 原文地址:https://www.cnblogs.com/cj5785/p/10664839.html
Copyright © 2011-2022 走看看