一. 泛型集合见上集详情
二. 泛型类
一般用于类中的属性类型不确定的情况下
class A<T> {//添加<类型参数>,参数如有多个用**逗号**分隔
private T data; //泛型参数作为属性类型
public A() {
}
public A( T data ) {
this.data = data;
}
public T getData() { // 返回泛型参数
return data;
}
}
public class Fan {
public static void main(String[] args){
//在实例化泛型类时,需要指明泛型类中的类型参数
A<String> a1 = new A<String>("hello");
System.out.println( a1.getData() ); //hello
A<Integer> a2 = new A<Integer>(100);
System.out.println( a2.getData() ); // 100
System.out.println( a1.getClass() == a2.getClass() ); // true,都是A泛型类
//getClass():返回当前对象的类的信息(Java反射中的方法)
}
}
附:限制泛型可用类型
◼ 在 Java 中默认可以使用任何类型来实例化一个泛型类对象。当然也可以对泛型类实例的类型进行限制。
◼ 语法格式如下:
class 类名称<T extends anyClass> { … }
◼ 使用泛型限制后,泛型类的类型必须实现或继承 anyClass 这个接口或类
◼ 无论anyClass是接口还是类,在进行泛型限制时都必须使用extends关键字
示例:
class ListClass<T extends List> {
}
class Test {
public static void main(String[] args) {
// 泛型参数使用ArrayList,OK
ListClass<ArrayList> lc1 = new ListClass<ArrayList>();
// 泛型参数使用LinkedList,OK
ListClass<LinkedList> lc2 = new ListClass<LinkedList>();
// 泛型参数使用HashMap,报错:HasMap没有实现List接口
// ListClass<HashMap> lc3=new ListClass<HashMap>();
} }
多参数泛型类
class Student<N, A, S> {
private N name; // 姓名
private A age; // 年龄
private S sex; // 性别
public Student(N name, A age, S sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public N getName() {
return name;
}
public void setName(N name) {
this.name = name;
}
public A getAge() {
return age;
}
public void setAge(A age) {
this.age = age;
}
public S getSex() {
return sex;
}
public void setSex(S sex) {
this.sex = sex;
}
}
public class test{
public static void main(String[] args){
Student<String, Integer, Character> stu = new Student<String, Integer, Character>("小明",19, '男');
String name = stu.getName();
Integer age = stu.getAge();
Character sex = stu.getSex();
System.out.println("姓名:" + name + ",年龄:" + age + ",性别:" + sex);
}
}
继承泛型类
class A<T> {
}
// 通常将父类的泛型类型保留(T)
// S是子类自己的类型参数
class B<S,T> extends A<T>{
}
// 测试代码:
A<String> b1 = new B<Integer, String>(); // OK
A<String> b2 = new B<Integer, Integer>(); // 报错,第二个必须是String类型
三.泛型方法
(是否拥有泛型方法,与其所在的类是不是泛型没有关系)
public static <T> void printArr( T[ ] arr ) {
for ( T e : arr ) {
System.out.printf("%s ", e);
}
System.out.println();
}
- 泛型方法声明都有一个参数声明部分,位于方法返回类型之前
- 参数声明部分可以包含一个或多个类型参数,参数间用逗号隔开(如<T,E>)
- 类型参数能被用来声明返回值类型,能作为泛型方法得到的实际参数类型的占位符
- 注意类型参数只能代表引用型类型,不能是原始类型(如int,double,char的等)
- 泛型方法体的声明和其他方法一样
public class Test {
public static <T> void printArr( T[ ] arr ) { // 泛型方法
for ( T e : arr ) {
System.out.printf("%s ", e);
}
System.out.println();
}
public static void main(String[] args) {
Integer[] a = { 1, 2, 3, 4, 5 }; // 不能使用int[]
String[] s = { "aaa","bbb" };
printArr(a);
printArr(s);
}
}
运行结果:
四. 通配符:使用?代替任意类型参数
//使用通配符代替任意类型参数
class A<T> { // 代码同前,略 }
public class Test {
public static void printData( A<?> data ) {
System.out.println("data :" + data.getData());
}
public static void main(String[] args) {
A<String> a1 = new A<String>("hello");
A<Integer> a2 = new A<Integer>(123);
printData(a1); // hello
printData(a2); // 123
}
}
给通配符设置限制
public static void printData( A<? extends 任意类> data ) {
… //限制形参只能是该类及其子类
}
public static void printData( A<? super 任意类> data ) {
… //限制形参只能是该类及其父类
}
五. 泛型接口
class A<T> { // 代码同前,略 }
interface IMy<T> { //泛型接口
T test();
}
class B implements IMy< A<String> >{ // 传入 A<String> //实现类
@Override
public A<String> test() {
A<String> x = new A<String>("hello");
return x;
}
}