Java 泛型 接口返回类 如何面对 空?

2021-04-10 14:04:43 +08:00
 RiceMarch

Java 接口返回类 中 泛型如何面对 返回值本应为null的情况??

在设计 web 应用中的返回基础类时,我会这样写

public class BaseResponse<T> implements Serializable {
   private static final long serialVersionUID = 1L;

    private int code;
    private String message;
    private T data;

    //... 省略构造方法等

    public static BaseResponse success() {
        return new BaseResponse();
    }
     public static BaseResponse success(String message) {
        return new BaseResponse(RespCodeEnum.SUCCESS, message);
    }
    
    //... 省略失败等
}

当在 controller 中 使用这些基础返回类进行数据包装时,通过泛型进行返回内容的指定

但 例如一些添加操作时,将不会有具体的返回值,只会返回 code 来判断是否操作成功

@PostMapping("/something")
public BaseResponse postSomething(@Valid @RequestBody Something request) {

    //添加操作

    //根据添加操作判断返回内容
    // if success
    return new BaseResponse.success();

    // if failed ...
}  

在上述代码中,我没有指定泛型类型,因为有些添加操作时,没有具体的返回值内容,我本来想写成 public BaseResponse<Void> postSomething,但在return时,却不知道该如何写。

想请问一下,指定泛型类型 理论上应该是都进行的(如果说错,请不要打我,个人想法 /(ㄒoㄒ)/~~),

但在这里如何进行正确的泛型类型指定呢(或者说需要指定泛型么)?

(太多知识不懂,天天来问 v 友,学到了很多,感谢感谢

4290 次点击
所在节点    Java
28 条回复
yuanmomo
2021-04-10 14:19:07 +08:00
没记错的话,我应该用的是问号
xarthur
2021-04-10 14:27:58 +08:00
不要用 null 不就行了……
用 Optional 。
我以为 null-safety 已经是个常识了(
xarthur
2021-04-10 14:28:51 +08:00
另外完全没看懂你的例子(
RiceMarch
2021-04-10 14:38:07 +08:00
@xarthur 可能我表达的不太好 hhhh,就是 BaseResponse 基础返回类中的 data 在一些情况下是没有值的,只有 code 和 message 有值,在确定 data 是没有值的情况下,我还想要在写 controller 方法的时候指定泛型类型,该怎么指定。
zhazi
2021-04-10 14:41:25 +08:00
Void
lwq84510
2021-04-10 14:43:11 +08:00
一楼是答案
aguesuka
2021-04-10 15:29:43 +08:00
不要使用问号作为泛型

@PostMapping("/something")
public BaseResponse<Void> /*改了这里*/postSomething(@Valid @RequestBody Something request) {

//添加操作

//根据添加操作判断返回内容
// if success
return new BaseResponse.<Void>/*会有灰色警告,即可将其省略*/success();

// if failed ...
}
wolfie
2021-04-10 15:31:01 +08:00
上面说了 问号,或者不理会编译器提醒 不加泛型也没问题。
passerbytiny
2021-04-10 15:40:19 +08:00
你需要构造的是:BaseResponse<Object>,在哪。任何类型可以承载 null,在你只需要它是 null 而不关心具体类型的时候,最高基类 Object 是一个勉强的选择。
passerbytiny
2021-04-10 15:46:21 +08:00
如果你这里的泛型,并不是给类似 Swagger 这样的自动生成 API 文档的工具用的,那么它是画蛇添足的东西,因为 Cortroller 方法是非框架代码中的最外层——除了框架不会有人从它那里获取返回值。

这里去掉泛型,直接将 data 定义成 Object 类型,会更好。
AoEiuV020
2021-04-10 15:47:59 +08:00
我一般用 String,
xuanbg
2021-04-10 15:54:39 +08:00
public class BaseResponse implements Serializable {
private static final long serialVersionUID = 1L;

private int code;
private String message;
private Object data;

//... 省略构造方法等

public static BaseResponse success() {
return new BaseResponse();
}
public static BaseResponse success(String message) {
return new BaseResponse(RespCodeEnum.SUCCESS, message);
}

//... 省略失败等
}

不用泛型,用 Object 。因为你不用知道类型也能序列化。
xuanbg
2021-04-10 16:02:22 +08:00
当然,你要用 swgger 这些自动化文档的话,返回的时候空也不影响啊。为啥要 new BaseResponse ? return this 就行了呀。

public BaseResponse success() {
setCode(200);
setMessage("请求成功");

return this;
}
Oktfolio
2021-04-10 16:30:24 +08:00
BaseResponse<?>
uselessVisitor
2021-04-10 17:00:00 +08:00
就是说你的 data 是 T 类型的?我们一般用<?>代替
EscYezi
2021-04-10 17:08:57 +08:00
RiceMarch
2021-04-10 17:24:48 +08:00
@passerbytiny 但如果是 Object 的话,我就不能在编译和运行前就知道返回值是否是我期望的内容了啊。
arthas2234
2021-04-10 17:44:58 +08:00
我都是在 controller 直接返回对象,没有返回值就是 void
然后实现 ResponseBodyAdvice 拦截 controller 方法默认返回参数,统一处理返回值
RiceMarch
2021-04-10 17:47:22 +08:00
@arthas2234 拓展了新思路 🐂
young1lin
2021-04-11 04:14:40 +08:00
我不建议你使用自定义的返回结果,使用 ResponseEntity<?> 就行了,真的,这个很重要。你必须了解各个状态码大概是什么意思,不要再二次包装 HTTP 状态了,那个不太好,对前端和对接的人,都是折磨,还要再解析一遍。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/769692

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX