转载

java 中abstract 为什么无法和static 组合使用

最近在重构open sdk的场景中,遇到了以下场景。

  1. 要针对针对不同的请求响应不同的数据。
  2. 能够明确告知业务请求成功/失败。
  3. 如果失败了,能够给出响应的错误信息。

首先,抽象了响应的数据结构,并通过两个静态方法来构建响应。

java 中abstract 为什么无法和static 组合使用

后来,我们构建了不同的Response类型,用以绑定对应不同的请求。这样就可以共用一个execute 方法。

AResponse aResponse = api.execute(aRequest);

(想象中)的类图关系:

java 中abstract 为什么无法和static 组合使用

(想象中)的客户端代码调度:

AResponse aResponse=AResponse.success("hello");
BResponse bResponse=BResponse.success(1);
CResponse cResponse=CResponse.success(now);
复制代码

(想象中)实现代码:

public static <T> BaseResponse<T> success(T data) {
    BaseResponse instance = getInstance();
    instance.setSuccess(true);
    instance.setData(data);
return instance;
    }
    
public static <T> BaseResponse<T> fail(String errorCode, String errorHint) {
    BaseResponse instance = getInstance();
    instance.setSuccess(false);
    instance.setErrorCode(errorCode);
    instance.setErrorHint(errorHint);
    return instance;
    }
    
static abstract <F extends BaseResponse> F getInstance();
复制代码

“static abstract F getInstance();” 报错“Illegal combination of modifiers :'abstract' and 'static'”

为什么不可以?

java语言的定义:

我们知道实例方法是可以使用abstract 描述的,不妨做一个比较:

静态方法 vs 实例方法

静态方法 实例方法
静态方法与它们所在的类相关联。可不需要实例来调用。 实例方法属于类的实例而不属于类,即可以在创建类的实例之后调用它们。
它们的设计目的是在同一个类中创建的所有对象之间共享。 从类创建的每个单独的实例都有自己的该类实例方法的副本。
静态绑定来解析。 动态绑定进行解析
无法覆盖。 可以被覆盖

因为静态绑定的缘故,无法覆盖就成了一个自然的推导。而“abstract”的存在即是为了进行子类行为覆盖父类规范的修饰符。因此,abstract' 和 'static‘ 无法组合使用。

逻辑和状态角度:

static 主要是关于无状态的逻辑计算,完成static 语句块或方法体的前提是“计算前,所有参与计算的因素都是确定的。

e.g.

我们无法将instance实例化这样的一个定义在静态环境里的行为延迟到运行时动态确定,当success 被执行的时候,它需要一个十分确定的参数 instance。

public static <T> BaseResponse<T> success(BaseResponse instance,T data) {
    instance.setSuccess(true);
    instance.setData(data);
    return instance;
}
复制代码

总结

所以abstract 为什么无法和static 组合使用?

  1. “逻辑和状态分离”原则的实践。
原文  https://juejin.im/post/5d067cc7f265da1b60290297
正文到此结束
Loading...