Java~泛型

本文介绍了Java中的泛型概念,通过示例展示了未使用泛型时可能出现的类型转换错误。泛型提供了一种在编译期间确保集合元素类型安全的方法,避免了运行时的ClassCastException。同时,文章还讨论了泛型在类、接口、方法上的应用,以及泛型接口和泛型方法的实现。此外,提到了泛型通配符的使用,包括无限制、向下限定和向上限定。最后,简述了增强for循环在遍历集合和数组时的优势和注意事项。
摘要由CSDN通过智能技术生成

/*
 * ArrayList存储字符串并遍历
 * 
 * 我们按照正常的写法来写这个程序, 结果确出错了。
 * 为什么呢?
 *         因为我们开始存储的时候,存储了String和Integer两种类型的数据。
 *         而在遍历的时候,我们把它们都当作String类型处理的,做了转换,所以就报错了。
 * 但是呢,它在编译期间却没有告诉我们。
 * 所以,我就觉得这个设计的不好。
 * 回想一下,我们的数组
 *         String[] strArray = new String[3];
 *         strArray[0] = "hello";
 *         strArray[1] = "world";
 *         strArray[2] = 10;
 * 集合也模仿着数组的这种做法,在创建对象的时候明确元素的数据类型。这样就不会在有问题了。
 * 而这种技术被称为:泛型
 * 
 * 泛型:是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
 * 格式:
 *         <数据类型>
 *         此处的数据类型只能是引用类型
 * 好处:
 *         A:把运行时期的问题提前到了编译期间
 *         B:避免了强制类型转换
 *         C:优化了程序设计,解决了黄色警告线
 */

package Generic;
import java.util.ArrayList;
import java.util.Iterator;

public class GenericDemo {
    public static void main(String[] args) {
        // 创建
        ArrayList array = new ArrayList();
//		ArrayList<String> array = new ArrayList<String>();

        // 添加元素
        array.add("hello");
        array.add("world");
        array.add("java");
       //  array.add(new Integer(100));
       // array.add(10); // JDK5以后的自动装箱
        // 等价于:array.add(Integer.valueOf(10));

        // 遍历
        Iterator it = array.iterator();
//		Iterator<String> it = array.iterator();
        while (it.hasNext()) {
            // ClassCastException
            String s = (String) it.next();
//			String s = it.next();
            System.out.println(s);
        }

        // 看下面这个代码(报错)
        // String[] strArray = new String[3];
        // strArray[0] = "hello";
        // strArray[1] = "world";
         //strArray[2] = 10;
    }
}

package Generic;

import java.util.ArrayList;
import java.util.Iterator;

/*
 * 泛型在哪些地方使用呢?
 * 		看API,如果类,接口,抽象类后面跟的有<E>就说要使用泛型。一般来说就是在集合中使用。
 */
public class ArrayListDemo1 {
    public static void main(String[] args) {
        // 用ArrayList存储字符串元素,并遍历。用泛型改进代码
        ArrayList<String> array = new ArrayList<String>();

        array.add("hello");
        array.add("world");
        array.add("java");

        Iterator<String> it = array.iterator();
        while (it.hasNext()) {
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("-----------------");

        for (int x = 0; x < array.size(); x++) {
            String s = array.get(x);
            System.out.println(s);
        }
    }
}
/*
hello
world
java
-----------------
hello
world
java
 */
import java.util.ArrayList;
        import java.util.Iterator;

/*
 * 需求:存储自定义对象并遍历。
 * A:创建学生类
 * B:创建集合对象
 * C:创建元素对象
 * D:把元素添加到集合
 * E:遍历集合
 */
public class ArrayListDemo2 {
    public static void main(String[] args) {
        // 创建集合对象
        // JDK7的新特性:泛型推断。
        // ArrayList<Student> array = new ArrayList<>();
        // 但是我不建议这样使用。
        ArrayList<Student> array = new ArrayList<Student>();

        // 创建元素对象
        Student s1 = new Student("曹操", 40); // 后知后觉
        Student s2 = new Student("蒋干", 30); // 不知不觉
        Student s3 = new Student("诸葛亮", 26);// 先知先觉

        // 添加元素
        array.add(s1);
        array.add(s2);
        array.add(s3);

        // 遍历
        Iterator<Student> it = array.iterator();
        while (it.hasNext()) {
            Student s = it.next();
            System.out.println(s.getName() + "---" + s.getAge());
        }
        System.out.println("------------------");

        for (int x = 0; x < array.size(); x++) {
            Student s = array.get(x);
            System.out.println(s.getName() + "---" + s.getAge());
        }
    }
}
/*
曹操---40
蒋干---30
诸葛亮---26
------------------
曹操---40
蒋干---30
诸葛亮---26
 */

package Generic;
public class ObjectTool {
    private Object obj;

    public Object getObj() {
        return obj;
    }

    public void setObj(Object obj) { // Object obj = new Integer(30);
        this.obj = obj;
    }
}
package Generic;

/*
 * 早期的时候,我们使用Object来代表任意的类型。
 * 向上转型是没有任何问题的,但是在向下转型的时候其实隐含了类型转换的问题。
 * 也就是说这样的程序其实并不是安全的。所以Java在JDK5后引入了泛型,提高程序的安全性。
 */
public class ObjectToolDemo {
    public static void main(String[] args) {
        ObjectTool ot = new ObjectTool();

        // 正常使用
        ot.setObj(new Integer(37));
        Integer i = (Integer) ot.getObj();
        System.out.println("年龄是:" + i);

        ot.setObj(new String("汪峰"));
        String s = (String) ot.getObj();
        System.out.println("姓名是:" + s);

        System.out.println("---------");
        ot.setObj(new Integer(30));
        // ClassCastException
        String ss = (String) ot.getObj();
        System.out.println("姓名是:" + ss);
    }
}

/*
 * 泛型类的测试
 */
public class ObjectToolDemo {
	public static void main(String[] args) {
		 ObjectTool ot = new ObjectTool();
		
		 ot.setObj(new String("金正恩"));
		 String s = (String) ot.getObj();
		 System.out.println("姓名是:" + s);
		
		 ot.setObj(new Integer(30));
		 Integer i = (Integer) ot.getObj();
		 System.out.println("年龄是:" + i);

//		 ot.setObj(new String("汪峰"));
//		 // ClassCastException
//		 Integer ii = (Integer) ot.getObj();
//		 System.out.println("姓名是:" + ii);

//		System.out.println("-------------");
//
//		ObjectTool<String> ot = new ObjectTool<String>();
//		// ot.setObj(new Integer(37)); //这个时候编译期间就过不去
//		ot.setObj(new String("汪峰"));
//		String s = ot.getObj();
//		System.out.println("姓名是:" + s);
//
//		ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
//		// ot2.setObj(new String("金正恩"));//这个时候编译期间就过不去
//		ot2.setObj(new Integer(30));
//		Integer i = ot2.getObj();
//		System.out.println("年龄是:" + i);
	}
}
package Generic;

 /*public class ObjectTool {   //1、不使用泛型时
 public class ObjectTool<T> {  //2、在类上使用泛型时
  /*public void show(String s) {
  System.out.println(s);
  }

  public void show(Integer i) {
  System.out.println(i);
 }

  public void show(Boolean b) {
  System.out.println(b);
  }
*/
 /* 	public void show(T t) {
 		System.out.println(t);
 	}
 }
*/
/*3、
 * 泛型方法:把泛型定义在方法上
 */
 public class ObjectTool {
 	public <T> void show(T t) {
 		System.out.println(t);
 	}
 }
package Generic;

public class ObjectToolDemo1 {
    public static void main(String[] args) {
  /* System.out.println("1、测试不使用泛型时");
        ObjectTool ot = new ObjectTool();
        ot.show("hello");
        ot.show(100);
        ot.show(true);
/*
hello
100
true
 */

     /*   System.out.println("2、测试在类上使用泛型时");
          ObjectTool<String> ot = new ObjectTool<String>();
         ot.show("hello");

          ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
         ot2.show(100);

          ObjectTool<Boolean> ot3 = new ObjectTool<Boolean>();
          ot3.show(true);
/*
hello
100
true

 */
        // 但是呢,谁说了方法一定要和类的类型的一致呢?
        // 要是类上没有泛型的话,方法还能不能接收任意类型的参数了呢?

        //3、测试定义泛型方法后
 		ObjectTool ot = new ObjectTool();
 		ot.show("hello");
 		ot.show(100);
 		ot.show(true);
         /*
hello
100
true

 */

    }
}
package Generic;
//实现类在实现接口的时候
//第一种情况:已经知道该是什么类型的了

//public class InterImpl implements Inter<String> {
//
//	@Override
//	public void show(String t) {
//		System.out.println(t);
//	}
// }
/*
 * 泛型接口:把泛型定义在接口上
 */
 interface Inter<T> {
    public abstract void show(T t);
}
//第二种情况:还不知道是什么类型的
 class InterImpl<T> implements Inter<T> {

    @Override
    public void show(T t) {
        System.out.println(t);
    }
}

public class InterDemo {
    public static void main(String[] args) {
        // 第一种情况的测试
        // Inter<String> i = new InterImpl();
        // i.show("hello");

        // // 第二种情况的测试
        Inter<String> i = new InterImpl<String>();
        i.show("hello");

        Inter<Integer> ii = new InterImpl<Integer>();
        ii.show(100);
        /*
        hello
        100
         */
    }
}
/*
 * 泛型高级(通配符)
 * ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
 * ? extends E:向下限定,E及其子类
 * ? super E:向上限定,E极其父类
 */
package Generic;
import java.util.ArrayList;
import java.util.Collection;
public class GenericDemo1 {
    public static void main(String[] args) {
        // 泛型如果明确的写的时候,前后必须一致
        Collection<Object> c1 = new ArrayList<Object>();
        // Collection<Object> c2 = new ArrayList<Animal>();
        // Collection<Object> c3 = new ArrayList<Dog>();
        // Collection<Object> c4 = new ArrayList<Cat>();

        // ?表示任意的类型都是可以的
        Collection<?> c5 = new ArrayList<Object>();
        Collection<?> c6 = new ArrayList<Animal>();
        Collection<?> c7 = new ArrayList<Dog>();
        Collection<?> c8 = new ArrayList<Cat>();

        // ? extends E:向下限定,E及其子类
        // Collection<? extends Animal> c9 = new ArrayList<Object>();
        Collection<? extends Animal> c10 = new ArrayList<Animal>();
        Collection<? extends Animal> c11 = new ArrayList<Dog>();
        Collection<? extends Animal> c12 = new ArrayList<Cat>();

        // ? super E:向上限定,E极其父类
        Collection<? super Animal> c13 = new ArrayList<Object>();
        Collection<? super Animal> c14 = new ArrayList<Animal>();
        // Collection<? super Animal> c15 = new ArrayList<Dog>();
        // Collection<? super Animal> c16 = new ArrayList<Cat>();
    }
}

class Animal {
}

class Dog extends Animal {
}

class Cat extends Animal {
}

/*
 * JDK5的新特性:自动拆装箱,泛型,增强for,静态导入,可变参数,枚举
 *
 * 增强for:是for循环的一种。
 *
 * 格式:
 *        for(元素数据类型 变量 : 数组或者Collection集合) {
 *       使用变量即可,该变量就是元素
 *     }
 *
 * 好处:简化了数组和集合的遍历。
 *
 * 弊端: 增强for的目标不能为null。
 * 如何解决呢?对增强for的目标先进行不为null的判断,然后在使用。
 */
package Generic;

import java.util.ArrayList;
import java.util.List;


public class ForDemo {
    public static void main(String[] args) {
        // 定义一个int数组
        int[] arr = { 1, 2, 3, 4, 5 };
        for (int x = 0; x < arr.length; x++) {
            System.out.println(arr[x]);
        }
        System.out.println("---------------");
        // 增强for
        for (int x : arr) {
            System.out.println(x);
        }
        System.out.println("---------------");
        // 定义一个字符串数组
        String[] strArray = { "林青霞", "风清扬", "东方不败", "刘意" };
        // 增强for
        for (String s : strArray) {
            System.out.println(s);
        }
        System.out.println("---------------");
        // 定义一个集合
        ArrayList<String> array = new ArrayList<String>();
        array.add("hello");
        array.add("world");
        array.add("java");
        // 增强for
        for (String s : array) {
            System.out.println(s);
        }
        System.out.println("---------------");


        System.out.println("---------------");

        List<String> list = null;
        // NullPointerException
        // 这个s是我们从list里面获取出来的,在获取前,它肯定还好做一个判断
        // 说白了,这就是迭代器的功能
        if (list != null) {
            for (String s : list) {
                System.out.println(s);
            }
        }
      /* // 增强for其实是用来替代迭代器的
        //ConcurrentModificationException
       for (String s : array) {
            if ("world".equals(s)) {
                array.add("javaee");
            }
        }

        System.out.println("array:" + array);*/
    }
}
/*
1
2
3
4
5
---------------
1
2
3
4
5
---------------
林青霞
风清扬
东方不败
刘意
---------------
hello
world
java
---------------
---------------

进程已结束,退出代码0
*/

 注:记笔记!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值