(一)泛型的基本概念
- 泛型指的就是在类定义的时候并不会设置类中的属性或方法中的参数的具体类型,而是在类使用时再进行定义。
如果要想进行这种泛型的操作,就必须做一个类型标记的声明。
- 泛型只能接受类,所有的基本数据类型必须使用包装类
(二)泛型类
- 泛型类的基本语法:
class MyClass< T > {
T value1;
}
注意事项:
(1)尖括号 <> 中的 T 被称作是类型参数,用于指代任何类型。实际上这个T你可以任意写,但出于规范的目的,Java还是建议我们用单个大写字母来代表类型参数。
(2)如果一个类被 的形式定义,那么它就被称为是泛型类。
(3)在定义类的时候,只指定类的泛型参数,只有在使用泛型类的时候,才会制定具体的参数类型。
(4)泛型类可以有多个参数。 - 泛型类的使用:
假设需要你定义一个描述坐标的程序类Point,需要提供两个属性x、y。对于这两个属性的内容可能有如下选择:int型,double型,字符串型。
在定义类的时候无法确定具体的使用类型,因此此时使用泛型类。
举例1:
package www.fanfan.com;
import www.fanfan.com.Point;
//1. 使用泛型类,指定参数类型
//泛型类中属性的类型与普通方法的参数类型可以与类中制定的参数类型一样
public class Point2<T> {
private T x;
private T y;
public void setX(T x) {
this.x = x;
}
public void setY(T y) {
this.y = y;
}
public T getX() {
return x;
}
public T getY() {
return y;
}
@Override
public String toString() {
return "Point2{" +
"x=" + x +
", y=" + y +
'}';
}
public static void main(String[] args) {
//使用泛型类时指定具体的参数类型
Point2<Integer> integerPoint2 = new Point2<>();
integerPoint2.setX(1);
integerPoint2.setY(2);
System.out.println(integerPoint2);
Point2<String> stringPoint2 = new Point2<>();
stringPoint2.setY("东京180°");
stringPoint2.setX("北纬30°");
System.out.println(stringPoint2);
}
}

(三)泛型方法
- 泛型方法与泛型类没有关系;
- 泛型方法的定义:
class MyClass{
public < T> void testMethod(T t) {
System.out.println(t);
}
} - 泛型方法与泛型类稍有不同的地方是,类型参数也就是尖括号那一部分是写在返回值前面的。 中的 T 被称为类型参数,而方法中的 T 被称为参数化类型,它不是运行时真正的参数。
- 声明的类型参数,其实也是可以当作返回值的类型的。
举例2:
泛型方法的使用:
package www.fanfan.com;
//泛型方法
public class Point4 {
public <T> void print(T o){
System.out.println(o);
}
public static void main(String[] args) {
Point4 point4 = new Point4();
point4.print(3);
point4.print("hello");
}
}
(四)泛型方法与泛型类
- 泛型方法与泛型类可以共存,两者各自独立;
- 泛型类和泛型方法 类型参数使用的字母最好区别开。
举例3:
package www.fanfan.com;
import org.omg.Messaging.SYNC_WITH_TRANSPORT;
//泛型类与泛型方法可以共存
public class Point5<T,E>{
private T x;
private E y;
public void setX(T x) {
this.x = x;
}
public void setY(E y) {
this.y = y;
}
public T getX() {
return x;
}
public E getY() {
return y;
}
@Override
public String toString() {
return "Point5{" +
"x=" + x +
", y=" + y +
'}';
}
//这是泛型类中的一个普通方法
//普通方法中类型参数与类名中的类型参数一致
public void test(T t){
System.out.println(t);
}
//泛型方法
public <X> void print(X o){
System.out.println(o);
}
public static void main(String[] args) {
Point5<Integer,Integer> integerIntegerPoint5 = new
Point5<>();
integerIntegerPoint5.setX(89);
integerIntegerPoint5.setY(90);
System.out.println(integerIntegerPoint5);
integerIntegerPoint5.test(66);
integerIntegerPoint5.print("hello");
}
}
(五)通配符
- 通配符的格式:
- 通配符:?
- 通配符 ? 下有两个子通配符
(1)? extends 类:设置泛型上限
(2)? super 类:设置泛型下限
- 通配符存在的意义:
解决参数统一问题,可以接收所有的泛型类型,但是又不能够让用户随意修改。
就是在泛型类之外的方法中使用泛型类的时候,并不指定具体类型,在类使用具体参数类型的时候自动调整为类中使用的具体参数类型。 - 通配符的使用
通配符在使用的时候不能修改对象的内容。
class Message<T>{
private T message;
public T getMessage() {
return message;
}
public void setMessage(T message) {
this.message = message;
}
}
public class MessageTest {
public static void main(String[] args) {
Message<String> mag = new Message<>();
mag.setMessage("hello");
fun(mag);
}
//使用通配符
//此时不能修改对象内容
public static void fun(Message<?> mag){
System.out.println(mag.getMessage());
}
//此处没有使用通配符,直接使用了具体类型String,因为泛型类使用的时候使用的具体类型为String,因此此处使用String也可以,但是使用其他类型就不可以
// public static void fun(Message<String> mag){
// System.out.println(mag.getMessage());
// }
}
- 泛型上限和泛型下限
(1)泛型上限可以用在泛型类上,泛型方法上,不能修改内容。
(2)泛型下限不可以用在泛型类中,只能用在方法上,可以修改内容。
(六)泛型接口
泛型接口的定义和泛型类的定义类似。
在实现泛型接口时候有两种实现方式:
- 在子类定义时继续使用泛型;
- 在子类实现接口的时候给出具体类型。
使用:
//1. 定义泛型接口
interface Person< T >{
...
}
//2. 在子类定义时继续使用泛型
class Student<T> implements Person<T>{
...
}
//3. 在子类实现接口的时候给出具体类型。
class Teacher implements Person<String>{
...
}
本文详细介绍了Java中的泛型,包括泛型的基本概念、泛型类的定义与使用、泛型方法的声明与调用、泛型方法与泛型类的关系、通配符的应用以及泛型接口的实现。泛型允许在类和方法中延迟指定数据类型,提高了代码的复用性和安全性。通过泛型上限和下限,可以灵活控制参数类型。
332

被折叠的 条评论
为什么被折叠?



