1. 泛型概述
泛型:JDK1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制
- 方便程序员解决问题,让运行事情问题减少,安全。
- 避免了强制转换的麻烦
package collectionDemo;
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
// 定义了一个ArrayList容器,容器里面装的都是String类型的元素
al.add("ab01");
al.add("ab021");
al.add("adc014");
Iterator<String> it = al.iterator();
while (it.hasNext()){
//String s = (String)it.next();
System.out.println(it.next().length());
}
}
}
输出结果:
4
5
6
2. 泛型使用
泛型格式:通过< >
来定义要操作的引用数据类型
在使用java提供的对象时,什么时候写泛型呢?
- 通常在集合框架中很常见,只要见到
< >
就要定义泛型。 - 其实
< >
就是用来接收类型的 - 当使用集合时,将集合中要存储的数据类型作为参数传递到
< >
中即可。
package collectionDemo;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class GenericDemo {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<String>(new LenComparator());
treeSet.add("abcd");
treeSet.add("cc");
treeSet.add("cba");
Iterator<String> it = treeSet.iterator();
while (it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
class LenComparator implements Comparator<String>{
public int compare(String s1, String s2){
int len1 = s1.length(), len2 = s2.length();
int num = len1-len2;
if(num == 0)
return s1.compareTo(s2);
return num;
}
}
输出:
cc
cba
abcd
3. 泛型类
什么时候定义泛型类?
当类中要操作的对象的引用数据类型不确定的时候,早期通过定义Object来完成扩展,
现在定义泛型来完成扩展。
泛型出现之前的做法:
package collectionDemo;
class Worker{
}
class Master{
}
// 泛型出现之前的做法,需要强转
class Tool{
private Object obj;
public void setWorker(Object obj) {
this.obj = obj;
}
public Object getWorker() {
return obj;
}
}
public class GenericDemo1 {
public static void main(String[] args) {
Tool t = new Tool();
t.setWorker(new Master());
Worker w = (Worker)t.getWorker();
}
}
结果:(编译成功,运行失败)
Exception in thread "main" java.lang.ClassCastException: collectionDemo.Master cannot be cast to collectionDemo.Worker
at collectionDemo.GenericDemo1.main(GenericDemo1.java:29)
改进——泛型类
package collectionDemo;
class Worker{
}
class Master{
}
class Utils<T>{
private T t;
public void setMaster(T t) {
this.t = t;
}
public T getMaster() {
return t;
}
}
public class GenericDemo1 {
public static void main(String[] args) {
Utils<Master> utilsMaster = new Utils<Master>();
utilsMaster.setMaster(new Master());
//utilsMaster.setMaster(new Worker()); // 编译失败
Utils<Worker> utilsWorker = new Utils<Worker>();
utilsWorker.setMaster(new Worker());
//utilsWorker.setMaster(new Worker()); // 编译失败
}
}
4.泛型方法
(1) 泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
package collectionDemo;
class Demo<T>{
public void show(T t){
System.out.println("show:"+t);
}
}
public class GenericDemo2 {
public static void main(String[] args) {
Demo<String> demoStr = new Demo<>();
demoStr.show("xixixi");
Demo<Integer> demoInt = new Demo<>();
demoInt.show(123);
}
}
输出:
xixixi
show:123
(2) 为了让不同方法可以操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上。
package collectionDemo;
class Demo{
public <T> void show(T t){
System.out.println("show:"+t);
}
}
public class GenericDemo2 {
public static void main(String[] args) {
Demo demo = new Demo();
demo.show("xixixi");
demo.show(123);
}
}
输出:
show:xixixi
show:123
5. 静态方法泛型
静态方法不可以访问类上定义的泛型
如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
package collectionDemo;
class Demo<T>{
public void show(T t){
System.out.println("show:"+t);
}
public <Q> void print(Q q){
System.out.println("print:"+q);
}
/*
会产生 Error:(13, 31) java: 无法从静态上下文中引用非静态 类型变量 T
public static void Method(T t){
System.out.println("method:"+t);
}
*/
public static <H> void Method(H h){
System.out.println("method:"+h);
}
}
public class GenericDemo2 {
public static void main(String[] args) {
Demo.Method("shh");
Demo.Method(123);
Demo<String> demo = new Demo<>();
demo.show("xixiix");
//demo.show(123); 编译失败
demo.print("ssss");
demo.print(123);
}
}
输出结果:
method:shh
method:123
show:xixiix
print:ssss
print:123
6. 泛型接口
package collectionDemo;
interface Inter<T>{
void show(T t);
}
class InterImp1 implements Inter<String>{
public void show(String t){
System.out.println("show:"+t);
}
}
class InterImp2<T> implements Inter<T>{
public void show(T t){
System.out.println("show:"+t);
}
}
public class GenericDemo3 {
public static void main(String[] args) {
InterImp1 inter = new InterImp1();
inter.show("shh");
InterImp2<Integer> integerInterImp2 = new InterImp2<>();
integerInterImp2.show(123);
}
}
输出:
show:shh
show:123
7. 泛型限定
(1) 麻烦
package collectionDemo;
import java.util.ArrayList;
public class GenericDemo4 {
public static void main(String[] args) {
ArrayList<String> al1 = new ArrayList<>();
al1.add("shh1");
al1.add("shh2");
al1.add("shh3");
ArrayList<Integer> al2 = new ArrayList<>();
al2.add(1);
al2.add(2);
al2.add(3);
}
}
(2) ?
是通配符
package collectionDemo;
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo4 {
public static void main(String[] args) {
ArrayList<String> al1 = new ArrayList<>();
al1.add("shh1");
al1.add("shh2");
al1.add("shh3");
ArrayList<Integer> al2 = new ArrayList<>();
al2.add(1);
al2.add(2);
al2.add(3);
printColl(al1);
printColl(al2);
}
public static void printColl(ArrayList<?> al1){
Iterator<?> it = al1.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
(3) error:ArrayList<Student1> al = new ArrayList<Person1>();
package collectionDemo;
import java.util.ArrayList;
import java.util.Iterator;
class Person1{
private String name;
private int age;
public Person1(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
class Student1 extends Person1{
Student1(String name, int age){
super(name,age);
}
}
public class GenericDemo4 {
public static void main(String[] args) {
ArrayList<Person1> al1 = new ArrayList<>();
al1.add(new Person1("shh1",1));
al1.add(new Person1("shh2",2));
al1.add(new Person1("shh3",3));
al1.add(new Person1("shh4",4));
ArrayList<Student1> al2 = new ArrayList<>();
al2.add(new Student1("gy",1));
//printColl(al2);
//Error 不兼容的类型: java.util.ArrayList<collectionDemo.Student1>无法转换为java.util.ArrayList<collectionDemo.Person1>
}
public static void printColl(ArrayList<Person1> al1){
Iterator<Person1> it = al1.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
(4) 泛型限定
?
是通配符,也叫占位符
? extends E
:可以接受E类型或者E的子类型,上限? super E
:可以接受E类型或者E的父类型,下限
package collectionDemo;
import java.util.ArrayList;
import java.util.Iterator;
class Person1{
private String name;
private int age;
public Person1(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
class Student1 extends Person1{
Student1(String name, int age){
super(name,age);
}
}
public class GenericDemo4 {
public static void main(String[] args) {
ArrayList<Person1> al1 = new ArrayList<>();
al1.add(new Person1("shh1",1));
al1.add(new Person1("shh2",2));
al1.add(new Person1("shh3",3));
al1.add(new Person1("shh4",4));
printColl(al1);
ArrayList<Student1> al2 = new ArrayList<>();
al2.add(new Student1("gy",1));
printColl(al2);
}
public static void printColl(ArrayList<? extends Person1> al1){
Iterator<? extends Person1> it = al1.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
运行结果:
collectionDemo.Person1@13b6d03
collectionDemo.Person1@f5f2bb7
collectionDemo.Person1@73035e27
collectionDemo.Person1@64c64813
collectionDemo.Student1@483bf400
8. 泛型限定2
应用实例:
TreeSet(Comparator<? extends E> comparator)
TreeSet(Comparator<? super E> comparator)
package collectionDemo;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class GenericDemo5 {
public static void main(String[] args) {
TreeSet<Student2> tree = new TreeSet<>(new Comp());
tree.add(new Student2("shh1"));
tree.add(new Student2("shh5"));
tree.add(new Student2("shh3"));
Iterator<Student2> it = tree.iterator();
while (it.hasNext()){
System.out.println(it.next().getName());
}
TreeSet<Worker2> tree1 = new TreeSet<Worker2>(new Comp());
tree1.add(new Worker2("...gy1"));
tree1.add(new Worker2("...gy5"));
tree1.add(new Worker2("...gy3"));
Iterator<Worker2> it1 = tree1.iterator();
while (it1.hasNext()){
System.out.println(it1.next().getName());
}
}
}
class Person2{
private String name;
public Person2(String name){
this.name = name;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
class Student2 extends Person2{
public Student2(String name){
super(name);
}
}
class Worker2 extends Person2{
public Worker2(String name){
super(name);
}
}
class Comp implements Comparator<Person2>{
public int compare(Person2 s1, Person2 s2){
return s1.getName().compareTo(s2.getName());
}
}
输出结果:
shh1
shh3
shh5
...gy1
...gy3
...gy5