Как преобразовать запечатанный класс Kotlin в класс Java

#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 (from kotlin.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?