回想一下,我们的数组
* String[] strArray = new String[3];
* strArray[0] = "hello";
* strArray[1] = "world";
* strArray[2] = 10;
集合也模仿着数组的这种做法,在创建对象的时候明确元素的数据类型。这样就不会在有问题了。
而这种技术被称为:泛型。
*
目录
泛型:
是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。参数化类型,把类型当作参数一样的传递。
* 格式:
* <数据类型>
* 此处的数据类型只能是引用类型(凡是可以创建对象即可new Object ;定义参数的时候可以大写的)。ArrayList<Boolean> arr=new ArrayList(); arr.add(false); ArrayList<Integer> i=new ArrayList<Integer>(); i.add(1); * 好处: * A:把运行时期的问题提前到了编译期间 * B:避免了强制类型转换 * C:优化了程序设计,解决了黄色警告线
泛型的由来:
早期:使用object来接受所有的传递参数
public class ObjectTool {
private Object obj;
public Object getObj() {
return obj;
}
public void setObj(Object obj) { // Object obj = new Integer(30);
this.obj = obj;
}
}
但是在实际的应用中,会存在类型的转换问题,所以Java提供了泛型来解决这个安全问题
ot.setObj(new Integer(30));
// ClassCastException
String ss = (String) ot.getObj();
System.out.println("姓名是:" + ss);
需求1:泛型存储元素
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);
}
需求2:用泛型存储自定义对象
ArrayList<Student> array = new ArrayList<Student>();
// 创建元素对象
Student s1 = new Student("jason", 40); // 后知后觉
Student s2 = new Student("tom", 30); // 不知不觉
Student s3 = new Student("jerry", 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());
}
System.out.println("------------------");
for (Student s : array) {
System.out.println(s.getName() + "---" + s.getAge());
}
泛型类:
ObjectTool.java:
/*
* 泛型类:把泛型定义在类上
*/
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
ObjectToolDemo.java:
ObjectTool<String> ot = new ObjectTool<String>();
// ot.setObj(new Integer(27)); //这个时候编译期间就过不去
ot.setObj(new String("jay"));
String s = ot.getObj();
System.out.println("姓名是:" + s);
ObjectTool<Integer> ot2 = new ObjectTool<Integer>();
// ot2.setObj(new String("Tom"));//这个时候编译期间就过不去
ot2.setObj(new Integer(27));
Integer i = ot2.getObj();
System.out.println("年龄是:" + i);
泛型方法:
ObjectTool.java:
//根据穿如参数的类型自动设置返回值类型
public <T> void show(T t) {
System.out.println(t);
}
//public class ObjectTool<T> {
// // 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);
// }
// }
/*
* 泛型方法:把泛型定义在方法上
*/
public class ObjectTool {
//根据穿如参数的类型自动设置返回值类型
public <T> void show(T t) {
System.out.println(t);
}
}
ObjectToolDemo.java:
// ObjectTool ot = new ObjectTool();
// ot.show("hello");
// ot.show(100);
// ot.show(true);
// 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);
// 如果还听得懂,那就说明泛型类是没有问题的
// 但是呢,谁说了我的方法一定要和类的类型的一致呢?
// 我要是类上没有泛型的话,方法还能不能接收任意类型的参数了呢?
// 定义泛型方法后
ObjectTool ot = new ObjectTool();
ot.show("hello");
ot.show(100);
ot.show(true);
ot.show("a");
泛型接口:
Inter.java:
public interface Inter<T> {
public abstract void show(T t);
}
InterImpl.java:
//实现类在实现接口的时候
//第一种情况:已经知道该是什么类型的了
//public class InterImpl implements Inter<String> {
//
// @Override
// public void show(String t) {
// System.out.println(t);
// }
// }
//第二种情况:还不知道是什么类型的
public class InterImpl<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
InterDemo.java:
// 第一种情况的测试
// 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);
泛型高级(通配符)
* ?:任意类型,如果没有明确,那么就是Object以及任意的Java类了
* ? extends E:向下限定,E及其子类
* ? super E:向上限定,E极其父类
public class GenericDemo {
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 {
}