我对泛型的理解,可简单看成是变量的通配符。
目录
一、泛型类
在类的申明时指定参数,即构成了泛型类。泛型类的类型参数部分可以有一个或多个类型参数,它们之间用逗号分隔。这些类称为参数化类或参数化类型,因为它们接受一个或多个参数。
在使用泛型的时候如果传入泛型实参,则会根据传入的泛型实参做相应的限制,此时泛型才会起到本应起到的限制作用,但是,泛型的类型参数只能是类类型,不能是简单类型。如果不传入泛型类型实参的话,在泛型类中使用泛型的方法或成员变量定义的类型可以为任何的类型。换句话说,泛型类可以看成普通类的工厂。
class Person<T> {
private T age;
public void setAge(T age) {
this.age = age;
}
public T getAge() {
return this.age;
}
}
public class Generics {
public static void main(String args[]) {
Person<String> p = new Person<String>();
p.setAge("3 years old");
System.out.println(p.getAge());
Person<Integer> p2 = new Person<Integer>();
p2.setAge(3);
System.out.println(p2.getAge());
}
}
编译运行结果:
3 years old
3
二、通配符
类型通配符一般是使用?代替具体的类型实参,注意, 此处的?和Number、String、Integer一样都是一种实际的类型,可以把?看成所有类型的父类。是一种真实的类型。实例如下所示:
class Person<T> {
private T age;
public void setAge(T age) {
this.age = age;
}
public T getAge() {
return this.age;
}
}
public class Generics {
public static void main(String args[]) {
Person<String> p = new Person<String>();
p.setAge("3 years old");
printInfo(p);
Person<Integer> p2 = new Person<Integer>();
p2.setAge(3);
printInfo(p2);
Person<?> p3;
p3 = p;
//p3.setAge("4 years");
p3.getAge();
}
public static void printInfo(Person<?> p) {
System.out.println(p.getAge());
}
}
编译运行结果:
3 years old
3
可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。
三、泛型方法
前面介绍了如何定义一个泛型类。其实我们还可以定义一个带有类型参数的泛型方法。如下所示:
public class Generics {
public static <T> T printInfo2(T...a) {
return a
}
}
printInfo2泛型方法定义在普通的类中,注意,类型变量放在修饰符(这里是public static)的后面,返回类型的前面。泛型方法可以定义在普通类中,也可以定义在泛型类中。实例如下所示(printInfo2是泛型方法):
class Person<T> {
private T age;
public void setAge(T age) {
this.age = age;
}
public T getAge() {
return this.age;
}
}
public class Generics {
public static void main(String args[]) {
Person<String> p = new Person<String>();
p.setAge("3 years old");
//System.out.println(p.getAge());
printInfo(p);
Person<Integer> p2 = new Person<Integer>();
p2.setAge(3);
//System.out.println(p2.getAge());
printInfo(p2);
Person<?> p3;
p3 = p;
//p3.setAge("4 years");
p3.getAge();
printInfo2(p);
printInfo2(p2);
printInfo2(p3);
}
public static void printInfo(Person<?> p) {
System.out.println(p.getAge());
}
/* printInfo2是泛型方法 */
public static <T> void printInfo2(Person<T> p) {
System.out.println(p.getAge());
}
}
编译运行结果:
3 years old
3
3 years old
3
3 years old
四、泛型类继承
如果不传入具体的类型,则子类也需要指定类型参数,
class Son<T> extends Test<T>{}
如果传入具体参数,则子类不需要指定类型参数
class Son extends Test<String>{}
class Person<T> {
private T age;
public void setAge(T age) {
this.age = age;
}
public T getAge() {
return this.age;
}
}
class Student<T> extends Person<T> {
}
class Student2 extends Person<String> {
}
public class Generics {
public static void main(String args[]) {
Person<String> p = new Person<String>();
p.setAge("3 years old");
//System.out.println(p.getAge());
printInfo(p);
Person<Integer> p2 = new Person<Integer>();
p2.setAge(3);
//System.out.println(p2.getAge());
printInfo(p2);
Person<?> p3;
p3 = p;
//p3.setAge("4 years");
p3.getAge();
printInfo2(p);
printInfo2(p2);
printInfo2(p3);
Student<Integer> s = new Student<Integer>();
s.setAge(10);
printInfo(s);
Student2 s2 = new Student2();
s2.setAge("11 years");
printInfo(s2);
}
public static void printInfo(Person<?> p) {
System.out.println(p.getAge());
}
public static <T> void printInfo2(Person<T> p) {
System.out.println(p.getAge());
}
}
3 years old
3
3 years old
3
3 years old
10
11 years
五、泛型接口
泛型接口与泛型类的定义基本一致
class Student<T> implements Person<T>
class Student2 implements Person<String>
interface Person<T> {
public void setAge(T age);
public T getAge();
}
class Student<T> implements Person<T> {
T age;
public void setAge(T age)
{
this.age = age;
}
public T getAge() {
return this.age;
}
}
class Student2 implements Person<String> {
String age;
public void setAge(String age)
{
this.age = age;
}
public String getAge() {
return this.age;
}
}
public class Generics {
public static void main(String args[]) {
Student<Integer> s = new Student<Integer>();
s.setAge(10);
printInfo(s);
Student2 s2 = new Student2();
s2.setAge("11 years");
printInfo(s2);
}
public static void printInfo(Person<?> p) {
System.out.println(p.getAge());
}
public static <T> void printInfo2(Person<T> p) {
System.out.println(p.getAge());
}
}
编译运行结果;
10
11 years
六、受限泛型
泛型的上限
使用一个泛型的时候,可以限制这个泛型是某个类或者是某个类的子类
<T extends Number> T只能是Number类或其子类
interface Person<T> {
public void setAge(T age);
public T getAge();
}
/* Integer, Float */
class Student<T extends Number> implements Person<T> {
T age;
public void setAge(T age)
{
this.age = age;
}
public T getAge() {
return this.age;
}
}
class Student2 implements Person<String> {
String age;
public void setAge(String age)
{
this.age = age;
}
public String getAge() {
return this.age;
}
}
public class Generics {
public static void main(String args[]) {
Student<Integer> s = new Student<Integer>();
s.setAge(10);
printInfo(s);
Student2 s2 = new Student2();
s2.setAge("11 years");
printInfo(s2);
}
public static void printInfo(Person<?> p) {
System.out.println(p.getAge());
}
public static <T> void printInfo2(Person<T> p) {
System.out.println(p.getAge());
}
}
编译运行结果:
10
11 years
泛型的下限
使用一个泛型的时候,可以限制这个泛型是某个类或者是某个类的父类
<? super String> 泛型只能是String类或其父类
interface Person<T> {
public void setAge(T age);
public T getAge();
}
class Student<T> implements Person<T> {
T age;
public void setAge(T age)
{
this.age = age;
}
public T getAge() {
return this.age;
}
}
class Student2 implements Person<String> {
String age;
public void setAge(String age)
{
this.age = age;
}
public String getAge() {
return this.age;
}
}
public class Generics {
public static void main(String args[]) {
Student<String> s = new Student<String>();
s.setAge("10");
printInfo(s);
Student2 s2 = new Student2();
s2.setAge("11 years");
printInfo(s2);
}
public static void printInfo(Person<? super String> p) {
System.out.println(p.getAge());
}
public static <T> void printInfo2(Person<T> p) {
System.out.println(p.getAge());
}
}
编译运行结果:
10
11 years