searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Java泛型迷雾:Service<T>、Service<Object>、Service<?>和S

2025-12-15 09:29:44
1
0

一、Service<t> - 泛型类的基本形式

Service<t>是我们定义的一个泛型类,这里的T是一个类型参数,它在类定义时并不确定具体类型,而是在实例化时由使用者指定,示例如下。

public class Service<T> {
    private T data;
    
    public void setData(T data) {
        this.data = data;
    }
    
    public T getData() {
        return data;
    }
}

// 使用时指定具体类型
Service<String> stringService = new Service<>();
stringService.setData("Hello");  // 正确
stringService.setData(123);      // 编译错误!类型不匹配

关键特点:

类型安全:编译器会在编译期进行类型检查

无需强制类型转换

代码可读性更好

二、Service - 参数化为Object类型

Service 是Service<t>的一个特例,其中类型参数T被具体指定为Object。

Service<Object> objectService = new Service<>();
objectService.setData("String");      // 正确
objectService.setData(123);           // 正确
objectService.setData(new Date());    // 正确

// 但是获取时需要强制类型转换
String str = (String) objectService.getData();  // 需要显式转换

关键特点:

可以存储任何类型的对象

失去了编译期类型安全检查的优势

获取数据时需要手动进行类型转换

与原始类型相比,它仍然是参数化类型

三、Service<?> - 通配符类型

Service<?>使用通配符?表示未知类型,这是Java泛型中处理灵活性的重要机制。

// 可以声明,但不能创建实例
Service<?> wildcardService;  // 正确
// Service<?> service = new Service<?>();  // 编译错误!

// 通常用于方法参数,表示接受任何类型的Service
public void processService(Service<?> service) {
    // 可以从service获取数据,但类型是Object
    Object obj = service.getData();
    
    // 不能向service设置数据(null除外)
    // service.setData("test");  // 编译错误!
    service.setData(null);      // 唯一允许的设置
}

关键特点:

表示"某种特定但未知的类型"

主要用于声明和参数,不能直接实例化

只读不写(除了null)

支持上下界通配符:Service<? extends Number>和Service<? super Integer>

四、Service - 原始类型(Raw Type)

直接使用Service而不带任何泛型参数,这就是所谓的原始类型。这是为了向后兼容Java 5之前的代码而保留的特性。

// 原始类型 - 完全不使用泛型
Service rawService = new Service();
rawService.setData("String");     // 正确,但有警告
rawService.setData(123);          // 正确,但有警告

// 获取数据时返回Object,需要强制转换
String str = (String) rawService.getData();  // 运行时可能抛出ClassCastException

关键特点:

完全绕过泛型类型检查

编译器会生成"unchecked"警告

与泛型之前的Java代码兼容

不推荐在现代Java代码中使用

总结:

类型 类型安全 是否需要类型转换 可读性 使用场景
Service 编译期检查 优秀 明确知道具体类型的场景
Service 部分安全 一般 需要存储多种类型但保留泛型结构
Service 部分安全 良好 方法参数、灵活接受多种泛型实例
Service 不安全 兼容旧代码,不推荐在新代码中使用
0条评论
0 / 1000
杨****攀
5文章数
0粉丝数
杨****攀
5 文章 | 0 粉丝
原创

Java泛型迷雾:Service<T>、Service<Object>、Service<?>和S

2025-12-15 09:29:44
1
0

一、Service<t> - 泛型类的基本形式

Service<t>是我们定义的一个泛型类,这里的T是一个类型参数,它在类定义时并不确定具体类型,而是在实例化时由使用者指定,示例如下。

public class Service<T> {
    private T data;
    
    public void setData(T data) {
        this.data = data;
    }
    
    public T getData() {
        return data;
    }
}

// 使用时指定具体类型
Service<String> stringService = new Service<>();
stringService.setData("Hello");  // 正确
stringService.setData(123);      // 编译错误!类型不匹配

关键特点:

类型安全:编译器会在编译期进行类型检查

无需强制类型转换

代码可读性更好

二、Service - 参数化为Object类型

Service 是Service<t>的一个特例,其中类型参数T被具体指定为Object。

Service<Object> objectService = new Service<>();
objectService.setData("String");      // 正确
objectService.setData(123);           // 正确
objectService.setData(new Date());    // 正确

// 但是获取时需要强制类型转换
String str = (String) objectService.getData();  // 需要显式转换

关键特点:

可以存储任何类型的对象

失去了编译期类型安全检查的优势

获取数据时需要手动进行类型转换

与原始类型相比,它仍然是参数化类型

三、Service<?> - 通配符类型

Service<?>使用通配符?表示未知类型,这是Java泛型中处理灵活性的重要机制。

// 可以声明,但不能创建实例
Service<?> wildcardService;  // 正确
// Service<?> service = new Service<?>();  // 编译错误!

// 通常用于方法参数,表示接受任何类型的Service
public void processService(Service<?> service) {
    // 可以从service获取数据,但类型是Object
    Object obj = service.getData();
    
    // 不能向service设置数据(null除外)
    // service.setData("test");  // 编译错误!
    service.setData(null);      // 唯一允许的设置
}

关键特点:

表示"某种特定但未知的类型"

主要用于声明和参数,不能直接实例化

只读不写(除了null)

支持上下界通配符:Service<? extends Number>和Service<? super Integer>

四、Service - 原始类型(Raw Type)

直接使用Service而不带任何泛型参数,这就是所谓的原始类型。这是为了向后兼容Java 5之前的代码而保留的特性。

// 原始类型 - 完全不使用泛型
Service rawService = new Service();
rawService.setData("String");     // 正确,但有警告
rawService.setData(123);          // 正确,但有警告

// 获取数据时返回Object,需要强制转换
String str = (String) rawService.getData();  // 运行时可能抛出ClassCastException

关键特点:

完全绕过泛型类型检查

编译器会生成"unchecked"警告

与泛型之前的Java代码兼容

不推荐在现代Java代码中使用

总结:

类型 类型安全 是否需要类型转换 可读性 使用场景
Service 编译期检查 优秀 明确知道具体类型的场景
Service 部分安全 一般 需要存储多种类型但保留泛型结构
Service 部分安全 良好 方法参数、灵活接受多种泛型实例
Service 不安全 兼容旧代码,不推荐在新代码中使用
文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0