先看一段代码:
public class Test {
public static void main(String[] args) {
//创建一个ArrayList集合
ArrayList list=new ArrayList();
list.add("java");
list.add(1234);
list.add(new Person("lili", Sex.女, 18));
//遍历集合
for (Object obj : list) {
System.out.println(obj);
}
}
}
上面创建一个集合ArrayList,ArrayList集合底层数据结构是数组,可以存放多种引用数据类型!所以放入集合的数据,可以是String,可以是Integer,可以是Person。那么假如,我现在想限定存入ArrayList的数据的类型,我只想放入String类型的数据,在java中,在JDK1.5之后提供了一个解决办法,就是:泛型(raw type),泛型表示 <> :(上面的代码在eclipse中会出现黄色警告,其实就是人家告诉你要用泛型呢)下面看代码加入泛型:我们从结果看到,加了泛型之后,再放入Integer类型,Person类型,就出错啦!这就是我们应用泛型的目的~~~也是个最基本的讲解 。接下来我们开始泛型的中级部分,这个不需要你记住,你学会了能看懂API就可以了,会跟人装逼就可以了 ;
我们开始讲解泛型的分类:【1】泛型类【2】泛型方法【3】泛型接口【1】泛型类:public class FanXing {
- 普通的类FanXing,在后面加上泛型 — 变成了泛型类
- <>中写什么都可以,什么字母都可以,只是一个占位符,只代表一种数据类型。API中常用E,E代表Element的缩写
- 我在这里 泛型用的AA ,就是为了让你看用啥字母都行
- AA的类型现在不确定 ,在创建对象的时候才确定具体的类型
}
public class TestFanXing {
public static void main(String[] args) {
//5.我们可以直接创建FanXing类的对象,但是有黄线警告,提醒你要加泛型
FanXing fx1=new FanXing();
//6.创建对象的时候,将类型确定为String
FanXing<String> fx2=new FanXing<String>();
//7.创建对象的时候,将类型确定为Person
FanXing<Person> fx3=new FanXing<Person>();
//8.创建对象的时候,将类型确定为Integer
FanXing<Integer> fx4=new FanXing<Integer>();
//9. <>中只能是引用数据类型
}
}API 中的示例:ArrayList就是一个泛型类,E就是一个泛型,具体的类型 ,在创建集合对象的时候才确定,例如:ArrayList list=new ArrayList();【2】泛型方法:在eclipse中先敲出下面的代码:一个一个讲解,首先我们看到FanXing是一个 泛型类。a方法:就是泛型类中的一个普通的方法b方法:参数BB是什么意思?是一种类型,但是BB跟AA的类型无关,BB的类型,要在调用b方法的时候才会确定!c方法:参数AA,确定了吗?确定了!为啥呢?在创建FanXing类的对象的时候,就指定了AA的类型,那么参数AA也就确定了啊!d方法,e方法 都是静态方法,但是一个可以一个不可以,为啥呢?因为静态方法在类被加载的时候就会被放入方法区了,e方法的BB参数,在类加载的时候也没有确定,无所谓的。但是d方法的AA参数,在这个方法被加载的时候,很可能还没有创建对象,那么AA的类型还没有确定呢!所以直接写肯定是不行 f方法:参数是AA类型的数组,AA类型在FanXing对象创建的时候就确定了!g方法:是一个可变参数,内部当做数组处理,Q的类型 在调用方法的时候才确定,返回值是一个数组。这个是模拟API中写的一个方法。ArrayList类的API示例: 看方法部分:E的类型,在创建ArrayList list=new ArrayList();对象的时候确定为String类型了,那么在调用add的时候,传入的必须是String类型!这个就好比是上面的g方法!【3】泛型接口,上面的懂了 ,这个就简单讲解
public interface TestFanXingInterface<WW> {
}
class A implements TestFanXingInterface{//当做普通的接口实现,报出警告
}
class B implements TestFanXingInterface<String>{//实现接口的时候,泛型种类确定
}
class C<WW> implements TestFanXingInterface<WW>{//实现接口的时候,泛型种类不确定,那么实现类也不确定
}
class D{
public static void main(String[] args) {
// TestFanXingInterface tfxi=new TestFanXingInterface();//接口不能创建对象
A a=new A();
B b=new B();
C c=new C();
C<String> cc=new C<String>();//在创建对象的时候确定类型
}
}
泛
型的高级应用,包括泛型的上限和泛型的下限,我们只讲一个,—泛型的上限,这个会了另一个就会了:1.先创建两个类:Person和Student,Student是Person的子类 (代码省略)2.创建集合代码:
public class Test {
public static void main(String[] args) {
//创建一个集合,里面只能存储Person类型的
ArrayList<Person> list=new ArrayList<Person>();
list.add(new Person("lili",18, 19.0));
list.add(new Person("nana", 18, 189.0));
for (Person person : list) {
System.out.println(person.getAge()+person.getHeight()+person.getName());
}
System.out.println("=================");
//创建一个集合,里面只能存储Student类型的
ArrayList<Student> list1=new ArrayList<Student>();
list1.add(new Student("lulu", 19, 200.0, 20095452));
list1.add(new Student("lily", 20, 10.4, 20095459));
for (Student s : list1) {
System.out.println(s.getAge()+s.getHeight()+s.getName());
}
System.out.println("=================");
// 想要调用bianLi方法的时候,传入list和list1都可以 ,要怎么办呢?看下个注释
bianLi(list);
bianLi(list1);
}
//利用泛型的上限。父类是Person 只要是Person的子类 都可以使用该方法
public static void bianLi(ArrayList<? extends Person> al){
for (Object obj : al) {
System.out.println(obj);
}
}
}
API中示例:Collection接口中泛型上限的示例:Collections类中泛型下限的示例:只要是T类型的父类 ,就都可以传入。。。