如何在Java中实现Kotlin密封类NetworkResult并正确访问?
用Java实现Kotlin密封类NetworkResult的等价方案
问题背景
现有Kotlin密封类定义如下:
sealed class NetworkResult<T>(val data: T? = null, val message: String? = null) { class Success<T>(data: T) : NetworkResult<T>(data) class Error<T>(message: String?, data: T? = null) : NetworkResult<T>(data, message) class Loading<T> : NetworkResult<T>() }
尝试转成Java实现时,无法访问内部类,调用NetworkResult.Success(response.body())时出现错误提示“Method call expected”,需要正确的Java实现方式及访问方法。
正确Java实现
Java没有密封类的概念,我们可以用抽象类+静态内部类来模拟相同功能,同时保证内部类可以直接通过外部类访问:
public abstract class NetworkResult<T> { private final T data; private final String message; // 构造方法,供内部子类调用 protected NetworkResult(T data, String message) { this.data = data; this.message = message; } // 获取数据 public T getData() { return data; } // 获取消息 public String getMessage() { return message; } // Success静态内部类 public static class Success<T> extends NetworkResult<T> { public Success(T data) { super(data, null); } } // Error静态内部类 public static class Error<T> extends NetworkResult<T> { public Error(String message, T data) { super(data, message); } // 重载构造方法,支持只传message的场景 public Error(String message) { super(null, message); } } // Loading静态内部类 public static class Loading<T> extends NetworkResult<T> { public Loading() { super(null, null); } } }
调用方式(解决“Method call expected”错误)
因为内部类都是static的,所以可以直接通过外部类调用构造方法创建实例:
// 创建Success实例 NetworkResult<User> successResult = new NetworkResult.Success<>(userData); // 创建Error实例(两种方式) NetworkResult<User> errorResult1 = new NetworkResult.Error<>("请求失败"); NetworkResult<User> errorResult2 = new NetworkResult.Error<>("请求失败", null); // 创建Loading实例 NetworkResult<User> loadingResult = new NetworkResult.Loading<>();
错误原因说明
你之前出现“Method call expected”的问题,大概率是因为:
- 内部类没有加
static修饰:非静态内部类必须依赖外部类实例才能创建,直接用NetworkResult.Success()会被编译器当成方法调用而非类构造 - 构造方法的访问权限不对:比如内部类的构造方法被设为私有,导致无法外部实例化
内容的提问来源于stack exchange,提问作者Bikram Shaw
相关产品推荐
相关产品推荐

