泛型介绍
- 泛型又称参数化类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题2)在类声明或实例化时只要指定好需要的具体的类型即可。
- Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生
- ClassCastException异常。同时,代码更加简洁、健壮
- 泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方
- 法的返回值的类型,或者是参数类型。
举例说明
public class Example {
public static void main(String[] args) {
ss<String> string = new ss<String>("aa");
/*
可以这样理解,上面的 ss 类,相当于
class ss{
String s; //E表示 s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
public ss(String s) { //E也可以是参数类型
this.s = s;
}
public String f(){ //返回类型使用 E
return s;
}
}
*/
}
}
//泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,
//或者是某个方法的返回值的类型,或者是参数类型
class ss<E>{
E s; //E表示 s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间,就确定E是什么类型
public ss(E s) { //E也可以是参数类型
this.s = s;
}
public E f(){ //返回类型使用 E
return s;
}
}
泛型的语法
泛型的声明
interface接口<T>{ } 和 class类<K,V>{ } //比如: List , ArrayList
说明:
1、其中,T,K,V不代表值,而是表示类型。
2、任意字母都可以。常用T表示,是Type的缩写
泛型的实例化:
要在类名后面指定类型参数的值(类型)。如:
1、List<String> strList = new ArrayList<String>0;[举例说明] 2、Iterator<Customer> iterator = customers.iterator();
举例说明
public class Exercise01 {
public static void main(String[] args) {
/**
练习:
1.创建3个学生对象
2.放入到 HashSet中学生对象,
3.放入到 HashMap中,要求Key是 String name, Value就是学生对象
4.使用两种方式遍历
*/
//使用泛型方式给 HashSet 放入3个学生对象
// E -> Student
HashSet<Student> student = new HashSet<>();
student.add(new Student("jack",18));
student.add(new Student("tom",22));
student.add(new Student("smith",6));
//增强for循环进行遍历
for (Student students :student) {
System.out.println(students);
}
System.out.println("=============================");
//使用泛型方式给 HashMap 放入3个学生对象
// K -> String , V -> Student
HashMap<String, Student> hashMap = new HashMap<>();
hashMap.put("jack",new Student("jack",18));
hashMap.put("tom",new Student("tom",22));
hashMap.put("smith",new Student("smith",6));
// 迭代器遍历
Set<Map.Entry<String, Student>> entries = hashMap.entrySet();
Iterator<Map.Entry<String, Student>> iterator = entries.iterator();
while (iterator.hasNext()) {
Map.Entry<String, Student> next = iterator.next();
System.out.println(next.getKey()+"-"+next.getValue());
}
}
}
class Student{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
输出:
Student{name='smith', age=6}
Student{name='tom', age=22}
Student{name='jack', age=18}
=============================
tom-Student{name='tom', age=22}
smith-Student{name='smith', age=6}
jack-Student{name='jack', age=18}
泛型使用细节
- interface List<T>{ } , public class HashSet<E>{ }..等等。 说明:T,E只能是引用类型
- 在给泛型指定具体类型后,可以传入该类型或者其子类类型
- 泛型的使用形式 :ArrayList<Integer> integers2 = new ArrayList<>();
- 如果我们这样写:List list3 = new ArrayList();默认给它的泛型是[ <E> E 就是 Object ]
举例说明
public class Exercise02 {
public static void main(String[] args) {
//1、各位泛型指向的数据类型,要求是引用类型,不能是基本数据类型
ArrayList<Integer> integers = new ArrayList<>(); //正确
//ArrayList<int> integers1 = new ArrayList<>(); //错误
//2、因为 E 指定了 A 类型,构造器传入了 new A()
//在给泛型指定具体类型后,可以传入该类型或者其子类类型
Pig<A> aPig = new Pig<>(new A());
Pig<A> aPig2 = new Pig<>(new B());
//3、泛型的使用形式
ArrayList<Integer> integers1 = new ArrayList<Integer>();
//在实际开发中,我们往往简写
//因为编译器会进行类型推断,推荐使用下面的写法
ArrayList<Integer> integers2 = new ArrayList<>();
//4、如果下面这样写,泛型默认是 Object
ArrayList arrayList = new ArrayList();//等价 ArrayList<Object> arrayList = new ArrayList<>();
}
}
class A{}
class B extends A{}
class Pig<E>{
E e;
public Pig(E e) {
this.e = e;
}
}