泛型
泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。
下面通过一个示例比较:
import java.util.ArrayList;
import java.util.List;
public class demo06 {
public static void main(String[] args) {
List list=new ArrayList();
list.add(100);
list.add("帅帅哒");
for (Object object : list) {
System.out.println(object);
}
System.out.println(list.get(0)+list.get(1)); //未对参数类型 java.lang.Object, java.lang.Object 定义运算符 +
/*使用泛型*/
List<String> list2=new ArrayList<String>();
list2.add(100); //编译报错
list2.add("帅帅哒");
}
}
分析:
1.上面的代码是没有使用泛型的,我们可以看到,简单的遍历是可以运行的,因为Object是所有类的父类,所以没有问题。但是一旦你要运行其他操作,类似与“+”.“-”之类的操作代码就会报错,因为没有定义。
2.本身list集合加入的类型也不一样,第一次加入的是Integer对象,第二次加入的String对象,本身就很容易出错,尤其在实际项目 开发中
3.然而下面的代码就是采用了泛型 “List< String>”也就是规定了集合中只能放入String对象,而不能放入其他对象,所以后面加入100,编译会出错。
自定义泛型
泛型类:
泛型类型用于泛型定义中的,称为泛型类
下面见代码:
public class demo06 {
public static void main(String[] args) {
Person person=new Person();
System.out.println(person+"\t"+person.getname());
Person person2=new Person(100);
System.out.println(person2+"\t"+person2.getname());
Person person3=new Person("帅帅哒");
System.out.println(person3+"\t"+person3.getname());
person3.setname(520);
System.out.println(person3+"\t"+person3.getname());
}
}
class Person<T>{
private T name;
public Person() {
// TODO 自动生成的构造函数存根
}
public Person(T name) {
this.name=name;
}
public T getname() {
return name;
}
public void setname(T name) {
this.name=name;
}
}
以下是输出结果:
Person@15db9742 null
Person@6d06d69c 100
Person@7852e922 帅帅哒
Person@7852e922 520
分析:
1.泛型类中的成员变量默认初始化是null
2.当使用泛型的时候,可以传递任意对象,并且修改也可以使用任意对象
泛型接口:
public class demo06{
public static void main(String[] args) {
text1<Integer> t1=new text1();
t1.add(100);
text1<String> t2=new text1();
t2.add("帅气");
//text2<Integer> t3=new text2(); //编译会出错,因为你已经确定了类继承的泛型类型
text2 t4=new text2();
t4.add("帅帅哒");
}
}
interface Person<T>{
void add(T t);
}
class text1<T> implements Person<T>{
@Override
public void add(T t) {
// TODO 自动生成的方法存根
System.out.println("我是:"+t);
}
}
class text2 implements Person<String>{
@Override
public void add(String t) {
// TODO 自动生成的方法存根
System.out.println("我是:"+t);
}
}
输出结果:
我是:100
我是:帅气
我是:帅帅哒
分析:
1.如果类继承泛型接口的时候,没有确定类型,那么类也必须带上泛型类型,否则会编译出错
2.如果没有确定泛型接口的类,也差不多类似与泛型类
3.确定了泛型接口的类,那么也就是固定一个类型
4.泛型接口主要用于生产器,定义一个接口,所有类型都可以继承
泛型方法:
返回类型前面使用泛型字母
见下面代码:
public class demo06 {
public static void main(String[] args) {
Person person=new Person(100);
System.out.println(person.getname());
System.out.println(person.setname(new Person("帅帅哒")));
}
}
class Person<T>{
private T name;
public Person(T name) {
this.name=name;
}
public <T>T setname(Person<T> person) {
return person.getname();
}
public T getname() {
return name;
}
}
输出如下:
100
帅帅哒
分析:
1.泛型方法的定义 :必须在方法返回值前加上泛型字符,否则不算泛型方法
2.泛型方法可以定义其他类型的泛型,与本身类中的泛型定义不一样
泛型通配符:
public class demo06 {
public static void main(String[] args) {
Person<String> person=new Person("帅帅哒");
Person<Integer> person2=new Person<Integer>(520);
person.readName(person);
person.readName(person2); //类型 Person<String> 中的方法 readName(Person<String>)对于参数(Person<Integer>)不适用
person.readName1(person2);
}
}
class Person<T>{
private T name;
public Person(T name) {
this.name=name;
}
public void readName(Person<T> person) {
System.out.println(person.name);
}
public void readName1(Person<?> person) {
System.out.println(person.name);
}
}
分析:
1. ?代表未知类型,类型参数赋予不确定值,任意类型
2.只能用在声明类型、方法参数上,不能用在定义泛型类上
3.在List集合定义的时候使用?,便可以new存放任意类型的集合
泛型的上下边界:
public class demo06 {
public static void main(String[] args) {
text<person> t1=new text<person>();
text<SupperPeople> t2=new text<SupperPeople>();
text<Student> t3=new text<Student>();
t1.name(t1);
t2.name(t2);
t3.name(t3);
t1.name1(t1);
t2.name1(t2);
t3.name1(t3);
}
}
class text<T>{
void name(text <? extends person> t) {
System.out.println("我是学生");
}
void name1(text<? super person> t) {
System.out.println("我是超人");
}
}
class SupperPeople{
}
class person extends SupperPeople{
}
class Student extends person{
}
代码输出:
t2.name(t2);
t3.name1(t3);
这两行代码报错,因为不符合约束条件
分析:
1.<? extends person>是表示传入的参数是person的的子类或者本身才可以运行
2.<? super person>是表示传入的参数是person的父类或者本身才可以运行
总结:
1.泛型只是编译的时候执行,实际运行中不会看到泛型,也就是看似类型不一样,实际上是一个类型
2.泛型字符一般有T、E、V、K,其中如果不够用,可以后面加数字,例如:T1、T2、T3
3.泛型目前更多的使用是在集合之中,具体的了解还需要多实践
4.有关泛型的继承、嵌套以及静态泛型没有介绍,可自行百度了解