Java学习之路(七):泛型
泛型的概述和基本使用
作用:把类型明确的工作推前到创建对象或者调用方法的时候
泛型是一种参数化类型,把类型当做参数一样传递来明确集合的元素类型
泛型的好处
- 提高安全性
- 省去强转的麻烦
泛型的基本使用
- 声明集合泛型的格式:List<String> li = new ArrayList<String>();
- <>中存放的必须是引用数据类型
泛型的注意事项
- 默认声明一个泛型集合,前后的类型要一致
- jdk1.7以上的新特性:在声明泛型类型的时候可以只声明前面的泛型(菱形泛型)
-
集合声明泛型:代表此类或者子类都可以成为集合的元素
- 声明的泛型类型一定要是引用类型
泛型ArrayList的遍历
package lesson03; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Demo01 { public static void main(String[] args){ List<String> li = new ArrayList<String>(); li.add("A"); li.add("B"); li.add("C"); Iterator<String> iterator = li.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } } }
package lesson03; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class Demo01 { public static void main(String[] args){ List<Student> li = new ArrayList<Student>(); li.add(new Student(11,"null11")); li.add(new Student(22,"null22")); li.add(new Student(33,"null33")); li.add(new Student(44,"null44")); for(Student fo:li){ System.out.println(fo); } } } class Student{ int age; String name; public Student(int age, String name) { super(); this.age = age; this.name = name; } public Student() { super(); // TODO Auto-generated constructor stub } @Override public String toString() { return "Student [age=" + age + ", name=" + name + "]"; } }
泛型类
定义格式:
public class 类名<泛型类型1,...> 注意:这里可以有多个,但不建议
我们一般写成 public class 类名<T>
注意事项:
- 泛型类型必须是引用类型
- T的值是在创建对象的时候出现的
泛型方法
定义格式:
public 返回类型 方法名(泛型类型 变量名)
注意:对象方法的泛型参数要与类中的泛型一致,不可以使用其他的名字
顺便补充:
泛型方法的定义:
public 返回类型(T) 方法名(泛型类型T 变量名)
具体的例子:
class Student<T>{ //泛型类 private T o; //泛型属性 public T getO() { return o; } public void setO(T o) { this.o = o; } public void fun1(T f1){} //泛型方法,无参数 public T fun2(int val){ //泛型方法,有参数 return null; } }
泛型接口
其实也就是:
public interface 接口名<数据类型>
使用场景:Dao (数据访问层)
泛型的高级使用(通配符)
- <?> 表示任意类型,如果没有明确表示,那么就是Object以及任何java类
- 一般是在传入参数的时候用的,表示接受任何类型
- ? extends E 向下限定,E以及其子类
- addAll方法,如果T是一个父类,那么添加的列表可以是子类,但是被添加的类表不能是子类
- ? super E 向上限定,E以及其父类
增强for循环
简化数组和Collection集合的遍历
格式:
for(元素数据类型 变量:数组或者Collection集合){
使用变量即可,这个变量就是数组或者Collection集合中的元素
}
其实在之前的ArrayList遍历中使用的便是增强for循环
注意:增强for循环不能边遍历,边删除元素,增强for循环的内部还是调用了
可变参数
定义方法的时候不知道我们该定义多少个参数。
格式:
修饰符 返回值类型 方法名(数据类型...变量名){}
注意事项:
- 这里的变量在内部就封装成了一个数组
- 如果一个方法有可变参数,并且有多个参数,可变参数要放在最后面
补充:
Arrays工具类的asList()方法的使用
List<String> li = Arrays.asList("A","B","C");
System.out.println(li);
在Arrays工具类的asList方法中就是使用了可变参数
Collection中的toArray(T[] a)将泛型转化为数组
package lesson05; import java.util.ArrayList; import java.util.List; public class Demo01 { public static void main(String[] args) { List<String> li = new ArrayList<String>(); li.add("A"); li.add("B"); li.add("C"); String[] arr = new String[3]; li.toArray(arr); for(String fo:arr){ System.out.println(fo); } } }
接下类是一个小例子
package lesson06; //一个例子 //学生类 //班级集合 //学校集合 import java.util.ArrayList; import java.util.List; public class Demo1 { public static void main(String[] args) { List<Student> class_li = new ArrayList<Student>(); class_li.add(new Student(1,"null1")); class_li.add(new Student(2,"null2")); class_li.add(new Student(3,"null3")); class_li.add(new Student(4,"null4")); List<List<Student>> school_list = new ArrayList<List<Student>>(); school_list.add(class_li); for(List<Student> class_item:school_list){ for(Student stu_item:class_item){ System.out.println(stu_item); } } } } class Student{ int age; String name; public Student() { super(); } public Student(int age, String name) { super(); this.age = age; this.name = name; } @Override public String toString() { return "Student [age=" + age + ", name=" + name + "]"; } }