#java #android #kotlin
#java #Android #kotlin
Вопрос:
Мне интересно, есть ли эквивалент в Java-коде для этого запечатанного класса kotlin
sealed class Resource<out T> {
class Loading<out T> : Resource<T>()
data class Success<out T>(val data: T) : Resource<T>()
data class Failure<out T>(val exception: Exception) : Resource<T>()
}
Комментарии:
1. Как насчет
Tools
->Kotlin
->Show Kotlin Bytecode
->Decompile to Java
?2. Я сделал это, но декомпилированный Java-код не ищет то, что я ожидаю
3.
sealed class
это не что иное, какabstract class
с дополнительными ограничениями по времени компиляции (объявлять все наследуемые классы в одном файле, возможность заполнять регистры «когда»), которых нет в java.4. Kotlin использует
DefaultConstructorMarker
class (fromkotlin.jvm.internal
) в качестве аргумента для закрытого класса, который является закрытым в этом пакете, и передает значение null этому классу всякий раз, когда класс расширяет его. Вы не можете воспроизвести поведение, потому что код не будет компилироваться, если вы попытаетесь получить доступ к закрытому конечному классу из другого пакета, чем у вас. Kotlin удается это сделать, потому что он скомпилирован из компилятора Kotlin, который не вмешивается в работу компилятора Java. Однако вы можете воспроизвести его, объединив эти классы в пакет и создав закрытый класс, к которому не может быть доступа ни один другой пакет.
Ответ №1:
Это то, что я использую в своем Java-проекте:
public class State<T> {
// States, use enums if possible
public static final int INITIAL = 0;
public static final int LOADING = 1;
public static final int SUCCESS = 2;
public static final int ERROR = 3;
private final int type;
private final T data;
private final Throwable error;
private State(@NonNull int type, @Nullable T d, @Nullable Throwable e) {
this.type = type;
this.data = d;
this.error = e;
}
public static <T> State<T> initial() {
return new State<>(INITIAL, null, null);
}
public static <T> State<T> loading() {
return new State<>(LOADING, null, null);
}
public static <T> State<T> success(T d) {
return new State<>(SUCCESS, d, null);
}
public static <T> State<T> error(Throwable e) {
return new State<>(ERROR, null, e);
}
public int getType() {
return type;
}
public T getData() {
return data;
}
public Throwable getError() {
return error;
}
}
Ответ №2:
Вот так (к сожалению, слишком подробно):
class Resource<T> {
class Loading extends Resource<T> { }
class Success extends Resource<T> {
@NonNull
T data;
public Success(T data) {
this.data = data;
}
}
class Failure extends Resource<T> {
@NonNull
Exception exception;
public Failure(Exception exception) {
this.exception = exception
}
}
}
Комментарии:
1. Внутренние классы должны быть помечены
static
, иначе вы не сможете создать их экземпляр, не имея экземпляра родительского класса. И чтобы действительно соответствовать запечатанным классам, родительский элемент должен быть абстрактным. Когда это используется в Java, у него не будет главной функции закрытых классов: использования их в исчерпывающемwhen
выражении.
Ответ №3:
Спасибо, Аугусто, я также использовал этот
public class StateData<T> {
@NonNull
private DataStatus status;
@Nullable
private T data;
@Nullable
private Throwable error;
public StateData() {
this.status = DataStatus.CREATED;
this.data = null;
this.error = null;
}
public StateData<T> loading() {
this.status = DataStatus.LOADING;
this.data = null;
this.error = null;
return this;
}
public StateData<T> success(@NonNull T data) {
this.status = DataStatus.SUCCESS;
this.data = data;
this.error = null;
return this;
}
public StateData<T> error(@NonNull Throwable error) {
this.status = DataStatus.ERROR;
this.data = null;
this.error = error;
return this;
}
public StateData<T> complete() {
this.status = DataStatus.COMPLETE;
return this;
}
@NonNull
public DataStatus getStatus() {
return status;
}
@Nullable
public T getData() {
return data;
}
@Nullable
public Throwable getError() {
return error;
}
public enum DataStatus {
CREATED,
SUCCESS,
ERROR,
LOADING,
COMPLETE
}
}
Комментарии:
1. могу я узнать, как вы используете это в java?