引例
public class Test{
private Object b;
public Object getB(){
return b;
}
private void setB(Object b){
this.b = b;
}
public static void main(String []args){
Test t = new Test();
t.setB(Boolean.valueOf(true));
System.out.println(t.getB());
t.setB(Boolean.valueOf("12.3"));
Float f = (Float)t.getB();
System.out.println(f);
}
}
实例的传入值和返回值可能与实例类型不符(主要在向下转型时,抛出ClassCastException异常)
定义泛型类
类名<T>
创建带泛型类的图书类
// Book.java
public class Book<T>{ // 带泛型的book<T>类
private T bookInfo; // 类型形参:书籍信息
public Book(T bookInfo){ // 参数为类型形参的构造方法
this.bookInfo = bookInfo; // 为书籍信息赋值
}
public T getBookInfo(){ // 获取书籍信息的值
return bookInfo;
}
}
// main.java
public class main {
public static void main(String[] args) {
// 创建参数为String类型的书名对象
Book<String> bookName = new Book<String>("《我爱Java》");
// 创建参数为String类型的作者对象
Book<String> bookAuthor = new Book<String>("Aim");
// 创建参数为Double类型的价格对象
Book<Double> bookPrice = new Book<Double>(12.3);
// 创建参数为Boolean类型的附赠源码
Book<Boolean> Source = new Book<Boolean>(true);
//控制台输出各项信息
System.out.println("书名" + bookName.getBookInfo());
System.out.println("作者" + bookAuthor.getBookInfo());
System.out.println("价格" + bookPrice.getBookInfo());
System.out.println("是否有附赠源码?" + Source.getBookInfo());
}
}
泛型的常规用法
定义泛型类的时候可以声明多个类型
class MyClass<T1,T2>{ }
定义泛型类时声明数组类型
//例子:定义泛型数组(将基本数据类型封装到一个类中)
public class ArrayClass <T>{
private T[] array;
public T[] getArray(){
return array;
}
public void setArray(T[] array){
this.array = array;
}
public static void main(String[] args) {
ArrayClass<String> demo = new ArrayClass<String>();
String value[] = {"成员1","成员2","成员3","成员4","成员5"};
demo.setArray(value);
String array[] = demo.getArray();
for(int i = 0;i < array.length;i ++){
System.out.println(array[i]);
}
}
}
集合类声明容器元素
常用被泛型化的集合类
集合类 | 泛型定义 |
---|---|
ArrayList | ArrayList |
HashMap | HashMap<K,V> |
HashSet | HashSet |
// 例子:使用泛型约束集合的元素类型
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class AnyClass {
public static void main(String[] args) {
// 定义ArrayList容器,设置容器内的值类型为Integer
ArrayList<Integer>a = new ArrayList<Integer>();
a.add(1);
for(int i = 0; i < a.size(); i ++){
// 根据容器的长度,循环显示容器内的值
System.out.println("获取ArrayList容器的成员值:" + a.get(i));
}
// 定义HashMap容器,设置容器的键名与键值类型分别为Integer型与String型
Map<Integer,String> m = new HashMap<Integer,String>();
for(int i = 0;i < 5;i ++){
m.put(i,"成员" + i);
}
for(int i = 0;i < m.size();i ++){
System.out.println("获取Map容器的成员值" + m.get(i));
}
}
}
泛型的高级用法
限制泛型可用类型
默认可以使用任何类型来实例化一个泛型类对象,但java中也对泛型类实例的类型作了限制
class 类名称<T extends anyClass>
// 限制泛型的类型必须为List的子类
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class LimitClass <T extends List>{
public static void main(String[] args) {
// 可以实例化已经实现List接口的类
LimitClass<ArrayList> l1 = new LimitClass<ArrayList>();
LimitClass<LinkedList> l2 = new LimitClass<LinkedList>();
// HashMap类没有实现List()接口
//LimitClass<HashMap> l3 = new LimitClass<HashMap>();
}
}
使用类型通配符
使用类型通配符的主要作用是在创建一个泛型类对象时限制这个泛型类的类型实现或继承某个接口或类的子类。
泛型类名称<? extends List>a = null;
同样的,如果实例化没有实现接口的泛型对象,编译器会报错。(这里是List接口)
除了可以实例化一个限制泛型类型的实例,还可以将该实例放置在方法的参数中。
public void doSomething(A<? extends List>a){ }
注意泛型类除了可以向上限制,还可以向下限制
A<? super List>a = null;
继承泛型类与实现泛型接口
定义为泛型的类和接口也可以被继承于实现
class ExtendClass<T1>{ }
class SubClass<T1,T2,T3>extends ExtendClass<T1>{ }
定义为泛型类的接口也可以被实现
interface SomeInterface<T1>{ }
class SubClass<T1,T2,T3> implements SomeInterface<T1>{ }