最近在重构open sdk的场景中,遇到了以下场景。
首先,抽象了响应的数据结构,并通过两个静态方法来构建响应。
后来,我们构建了不同的Response类型,用以绑定对应不同的请求。这样就可以共用一个execute 方法。
AResponse aResponse = api.execute(aRequest);
(想象中)的类图关系:
(想象中)的客户端代码调度:
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 组合使用?