Kotlin: при доступе к Enum Value генерируется nullpointerexception - PullRequest
0 голосов
/ 26 апреля 2020

Я пытаюсь передать перечисление в качестве параметра другому классу, чтобы я мог переопределить его цену Значение. Вот мой подход:

Базовый класс Product:

open class Product(val productName: String, open val price: Double) {
    val profit = price
}

Enum class:

enum class Discount(val factor: Int) {
    BIGSALE(20),
    LITTLESALE(10),
    NOSALE(0)
}

Продукт со скидкой:

class DiscountProduct(
    val discount: Discount,
    productName_param: String, price_param: Double
) : Product(productName_param, price_param) {

    // Nullpointer Exception
    override val price: Double
        get() = super.price - ((super.price / 100) * discount.factor)
}

App ( main):

val newProduct = DiscountProduct(Discount.BIGSALE, "Prod1", 100)

Я ценю любую помощь. Спасибо!

ОШИБКА:

Exception in thread "main" java.lang.NullPointerException
    at DiscountProduct.getPrice(DiscountProduct.kt:6)
    at Product.<init>(Product.kt:2)
    at DiscountProduct.<init>(DiscountProduct.kt:3)
    at AppKt.main(App.kt:2)
    at AppKt.main(App.kt)

1 Ответ

2 голосов
/ 26 апреля 2020

Фактический конструктор для DiscountProduct, если рассматривать его как код Java, будет выглядеть примерно так:

public DiscountProduct(@NotNull Discount discount, @NotNull String productName_param, double price_param) {
    Intrinsics.checkParameterIsNotNull(discount, "discount");
    Intrinsics.checkParameterIsNotNull(productName_param, "productName_param");
    super(productName_param, price_param);
    this.discount = discount;
}

Таким образом, конструктор super (т.е. конструктор Product) сначала вызывается, а затем инициализируется discount член. Конструктор

Product выглядит примерно так:

public Product(@NotNull String productName, double price) {
    Intrinsics.checkParameterIsNotNull(productName, "productName");
    super();
    this.productName = productName;
    this.price = price;
    this.profit = this.getPrice();
 }

Когда вы получаете this.profit = this.getPrice(); (что соответствует kotlin line val profit = price) вы вызываете метод DiscountProduct getPrice, который пытается использовать элемент discount, который еще не был инициализирован. И именно поэтому вы получаете NullPointerException.


Вероятно, есть несколько различных способов, которыми вы могли бы это исправить. Одним из возможных решений было бы сделать profit ленивым свойством, чтобы оно не инициализировалось до тех пор, пока вы в первый раз не попытаетесь его использовать:

val profit: Double by lazy { price }

Другое возможное решение будет:

val profit: Double get() = price

Разница между этим и ленивым свойством заключается в том, что здесь цена рассчитывается каждый раз, когда вы используете profit, а не только в первый раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...