泛型
泛型是一种把类型明确的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。是参数化类型。
参数化类型:
- 把类型当作是参数一样传递
<数据类型>
只能是引用类型
ArrayList<String> list = new ArrayList<String>();
Iterator<String> it = list.iterator();
泛型的好处:
1.避免了强制类型转换;
2.把运行期间的问题提前到了编译期间;
3.优化了程序设计,解决了黄色警告线。
泛型类
泛型类就是把泛型定义在类上,用户使用该类的时候,才把类型明确下来…这样的话,用户明确了什么类型,该类就代表着什么类型…用户在使用的时候就不用担心强转的问题,运行时转换异常的问题了。
public class ObjectTool<T> {
private T obj;
public T getObj() {
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
在调用类的时候,
public class ObjectToolDemo {
public static void main(String[] args) {
ObjectTool<String> ob = new ObjectTool<String>(); //< >里是什么类型 T 就代表什么类型
ob.setObj(new String("风🌤🐏"));
System.out.println(ob.getObj());
}
}
泛型方法
格式:
public <T> xxxx(){
}
逻辑实例:
public class ObjectToolDemo {
public static void main(String[] args) {
ObjectToolDemo ob2 = new ObjectToolDemo();
ob2.show("String类型");
ob2.show(100);
ob2.show(true);
}
//泛型方法
public <T> void show(T t) {
System.out.println(t);
}
}
泛型类派生出的子类
前面我们已经定义了泛型类,泛型类是拥有泛型这个特性的类,它本质上还是一个Java类,那么它就可以被继承
那它是怎么被继承的呢??这里分两种情况
- 子类明确泛型类的类型参数变量
- 子类不明确泛型类的类型参数变量
子类明确泛型类的类型参数变量
- 泛型接口
/*
把泛型定义在接口上
*/
public interface Inter<T> {
public abstract void show(T t);
}
- 实现泛型接口的类…
/**
* 子类明确泛型类的类型参数变量:
*/
public class InterImpl implements Inter<String> {
@Override
public void show(String s) {
System.out.println(s);
}
}
子类不明确泛型类的类型参数变量
- 当子类不明确泛型类的类型参数变量时,外界使用子类的时候,也需要传递类型参数变量进来,在实现类上需要定义出类型参数变量
/**
* 子类不明确泛型类的类型参数变量:
* 实现类也要定义出<T>类型的
*
*/
public class InterImpl<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
测试代码:
public static void main(String[] args) {
//测试第一种情况
//Inter<String> i = new InterImpl();
//i.show("hello");
//第二种情况测试
Inter<String> ii = new InterImpl<>();
ii.show("100");
}
值得注意的是:
- 实现类的要是重写父类的方法,返回值的类型是要和父类一样的!
- 类上声明的泛形只对非静态成员有效
泛型通配符
-
?
- 任意类型,如果没有明确,那么就是Object以及任意的Java类
-
? extends E
- 向下限定,E 及其子类
-
? super E
- 向上限定,E 及其父类
逻辑实例:
public class demo4 {
Collection<?> c1 = new ArrayList<String>();
Collection<?> c2 = new ArrayList<Integer>();
Collection<?> c3 = new ArrayList<Boolean>();
Collection<? extends Animal> c4 = new ArrayList<Object>(); //error, ?只能是Animal及Animal的子类
Collection<? extends Animal> c5 = new ArrayList<Animal>();
Collection<? extends Animal> c6 = new ArrayList<Dog>();
Collection<? extends Animal> c7 = new ArrayList<Cat>();
Collection<? super Animal> c8 = new ArrayList<Object>();
Collection<? super Animal> c9 = new ArrayList<Animal>();
Collection<? super Animal> c10 = new ArrayList<Dog>(); //error, ?只能是Animal及Animal的父类
Collection<? super Animal> c11 = new ArrayList<Cat>(); //error, ?只能是Animal及Animal的父类
}
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
增强 for
格式:
for(元素数据类型 变量 : 数组或者Collection集合){
使用变量即可,该变量就是元素
}
逻辑实例:
public class demo5 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("hello");
c.add("world");
for(String s:c) {
System.out.println(s);
}
}
}
注意:增强for的目标不能为 NULL。
增强for可以替代迭代器:
public class demo5 {
public static void main(String[] args) {
Collection<String> c = new ArrayList<String>();
c.add("hello");
c.add("world");
// for(String s:c) {
// System.out.println(s);
// }
Iterator it = c.iterator();
while(it.hasNext()) {
String s = (String)it.next();
System.out.println(s);
}
}
}