如何将Kotlin密封类转换为Java代码并简化重复类实现逻辑
把Kotlin密封类TokenCommandResult转Java,减少重复代码的方案
作为Kotlin新手刚转Java,遇到这种需要重复编写相似子类的情况确实有点麻烦,下面给你几种可行的方案,从基础实现到简化优化都有:
方案1:Java 17+ 密封类(最贴近Kotlin原逻辑)
如果你已经在使用Java 17或更高版本,Java已经支持sealed关键字了,这是最贴近Kotlin密封类的实现方式,能保证类型安全性:
public sealed class TokenCommandResult permits TokenCommandResult.Success, TokenCommandResult.Error, TokenCommandResult.Fault { // Success子类 public static final class Success extends TokenCommandResult { private final OIDCTokenResponse response; public Success(OIDCTokenResponse response) { this.response = response; } public OIDCTokenResponse getResponse() { return response; } } // Error子类 public static final class Error extends TokenCommandResult { private final TokenErrorResponse error; public Error(TokenErrorResponse error) { this.error = error; } public TokenErrorResponse getError() { return error; } } // Fault子类 public static final class Fault extends TokenCommandResult { private final Throwable exception; public Fault(Throwable exception) { this.exception = exception; } public Throwable getException() { return exception; } } }
对应的分支判断(替代Kotlin的when),可以用Java 17+支持的instanceof模式匹配:
if (result instanceof TokenCommandResult.Success success) { printToken(format, success.getResponse().getOidcTokens().getAccessToken().getValue()); } // 可以继续加else if处理Error和Fault else if (result instanceof TokenCommandResult.Error error) { // 处理错误逻辑 } else if (result instanceof TokenCommandResult.Fault fault) { // 处理异常逻辑 }
方案2:用泛型抽象类减少重复代码(兼容低版本Java)
如果你的项目还在用Java 17以下的版本,没法用密封类,那可以通过泛型抽象类来避免重复编写相似的子类结构:
首先定义一个带泛型的抽象内部类,把公共的字段和getter逻辑抽出来:
public abstract class TokenCommandResult { // 私有构造函数,禁止外部继承,模拟密封类的类型安全 private TokenCommandResult() {} // 泛型抽象类封装公共逻辑 private abstract static class Result<T> extends TokenCommandResult { private final T value; protected Result(T value) { this.value = value; } public T getValue() { return value; } } // Success直接继承泛型Result,指定类型为OIDCTokenResponse public static final class Success extends Result<OIDCTokenResponse> { public Success(OIDCTokenResponse response) { super(response); } } // Error继承泛型Result,指定类型为TokenErrorResponse public static final class Error extends Result<TokenErrorResponse> { public Error(TokenErrorResponse error) { super(error); } } // Fault继承泛型Result,指定类型为Throwable public static final class Fault extends Result<Throwable> { public Fault(Throwable exception) { super(exception); } } }
这样每个子类只需要写构造函数,不用重复写字段和getter了。对应的分支判断可以这样写:
if (result instanceof TokenCommandResult.Success success) { OIDCTokenResponse response = success.getValue(); printToken(format, response.getOidcTokens().getAccessToken().getValue()); } else if (result instanceof TokenCommandResult.Error error) { TokenErrorResponse err = error.getValue(); // 处理错误 } else if (result instanceof TokenCommandResult.Fault fault) { Throwable ex = fault.getValue(); // 处理异常 }
额外提示:模拟Kotlin密封类的类型安全
如果用Java低于17的版本,把TokenCommandResult的构造函数设为私有,就能禁止外部继承它,保证只有Success、Error、Fault这三个子类,和Kotlin密封类的类型安全效果一致。
内容的提问来源于stack exchange,提问作者user15826601
相关产品推荐
相关产品推荐

