泛型
1063字约4分钟
2025-09-23
泛型
- 编译的时候会检查元素的类型,提高安全性
- 减少类型的转换,提高效率
- 不会提示编译警告
- 普通成员可以使用泛型
- 使用泛型的数组,不能被初始化
- 静态方法和静态类不能使用泛型
- 如果创建对象时,没有指定类型,则默认为Object类
- 因为接口中的属性默认是公开静态的常量,所以在接口中不能使用泛型作为属性
public class Fan01 {
public static void main(String[] args) {
ArrayList<Dog> list = new ArrayList<Dog>();
list.add(new Dog("xiaohuang", 3));
list.add(new Dog("xiaohua", 1));
// 非Dog对象的对象无法添加到list集合中
// list.add(new Cat("xiaohua", 1));
// 遍历元素的时候不需要向下转型就可以调用对象元素
// 故效率提高
for (Dog o : list) {
// Dog d = (Dog) o;
System.out.println(o.getName());
}
}
}
class Dog {
String name;
int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
// set和get方法省略...
}
泛型类
public class Fan02 {
public static void main(String[] args) {
Person<String> p = new Person<String>("he");
System.out.println(p.Cla().getClass()); // String
/*
* 上面的泛型调用等同于下面的代码,将E变成自定义的类
* class Person<String> {
String name;
public Person (String name) {
this.name = name;
}
public String getE() {
return name;
}
}
* */
// 小括号中之所以不能使用数字,是因为你的泛型是String类
// 所以构造器中的E也就是String类,自然就不能传入int类型的值
// Person<String> p = new Person<String>(123);
Person<Integer> p1 = new Person<Integer>(123);
System.out.println(p1.Cla().getClass()); // Integer
}
}
class Person<E> {
E name;
public Person (E name) {
this.name = name;
}
public E Cla() {
return name;
}
}
给泛型指定具体类型后,可以传入该类型或者该类型的子类
public class Fan04 {
public static void main(String[] args) {
// B 继承 A
// 所以A泛型可以传入B类型
C<A> a = new C<>(new A());
C<A> b = new C<>(new B());
}
}
class A {}
class B extends A {}
class C<E> {
E s;
public C(E s) {
this.s = s;
}
}
调用对象属性
public class Fan04 {
public static void main(String[] args) {
ArrayList<C> c = new ArrayList<>();
c.add(new C("he"));
c.add(new C("java"));
System.out.println(c.get(1).n); // java
}
}
class C<E> {
E s;
String n;
public C(E s) {
this.s = s;
}
public C(String n) {
this.n = n;
}
@Override
public String toString() {
return n;
}
}
泛型接口
因为接口中的属性默认是公开静态的常量,所以在接口中不能使用泛型作为属性
interface Com<T, R> {
// T t; 错误的
void A(T t, R r);
R B(R r);
}
interface Red extends Com<Double, String> {}
class Blue implements Red {
// 因为实现了Red接口,Red接口继承Com接口
// 所以对应的泛型也要实现
@Override
public void A(Double aDouble, String s) {}
@Override
public String B(String s) {
return null;
}
}
// 这里的泛型如果不定义的话则默认为 Object
class Yellow implements Com<Integer, Double> {
@Override
public void A(Integer integer, Double aDouble) {}
@Override
public Double B(Double aDouble) {
return null;
}
}
泛型方法
public class Fan06 {
public static void main(String[] args) {
Tom tom = new Tom();
tom.blue("tom", 5);
Jerry<String, Integer> jerry = new Jerry<>();
jerry.black("jerry", 4);
}
}
class Tom {
// 泛型方法
public <T, R> void blue(T t, R r) {
System.out.println(t); // tom
System.out.println(r); // 5
}
}
class Jerry<U, M> {
// 泛型方法
public <A, B> void black(A a, B b) {
System.out.println(a); // jerry
System.out.println(b); // 4
}
// 不是泛型方法,只是调用了泛型
public void greed(U u) {}
}
泛型继承
public class Fan07 {
public static void main(String[] args) {
List<Object> list1 = new ArrayList<>();
List<String> list2 = new ArrayList<>();
List<AA> list3 = new ArrayList<>();
List<BB> list4 = new ArrayList<>();
List<CC> list5 = new ArrayList<>();
Blue1(list1);
Blue1(list2);
Blue1(list5);
Blue2(list1); // Object是BB的父类
// Blue2(list2); 报错,因为String和BB没关系
Blue2(list3); // AA是BB的父类
Blue2(list4); // 接受本身
// Blue2(list5); 报错,因为CC是BB的子类
// Blue3 同理...
}
// 接受所有泛型
public static void Blue1(List<?> c) {}
// 接受BB或者BB的父类(泛型)
public static void Blue2(List<? super BB> c) {}
// 接受BB或者BB的子类(泛型)
public static void Blue3(List<? extends BB> c) {}
}
class AA {}
class BB extends AA {}
class CC extends BB {}
练习
public class Homework03 {
public static void main(String[] args) {
Pig<Double, String, Integer> p = new Pig<>();
// 这里的泛型指定了类型,T为Double类
p.setT(1.1);
// 没有指定泛型类型,默认为Object
// 所以传入字符串是正常的
Pig p1 = new Pig();
p1.setT("1.1");
}
}
class Pig<T, R, M> {
T t;
R r;
M m;
public Pig() {}
public void setT(T t) {
this.t = t;
}
}