Каковы различия между свойствами класса Kotlin и полями класса Java - PullRequest
1 голос
/ 23 июня 2019

Я начал изучать Котлин.Мой текущий опыт работы с Java.Я обнаружил, что свойства классов в Kotlin довольно сильно отличаются от полей классов в Java, даже если они выглядят одинаково.В своем вопросе я хотел бы собрать воедино все технические различия между этими двумя.Это то, что я уже понял:

Поле Java и скрытие против свойств Kotli и переопределение
(и фактически это подтолкнуло меня к написанию этого поста):

В Java поле базового класса скрыто полем с тем же именем в производном классе, поэтому используемое поле зависит от типа ссылки на объект, который содержит поле, а не от типа объектасам по себе (поля не переопределяются, как методы, поэтому они не зависят от типа объекта во время выполнения).Например, этот код:

class A {
    public String name = "A";
    public void printMessage() {
        System.out.println("Field accessed in method declared inside class A invoked form an object of " + getClass() + " : " + name);
    }
}

class B extends A{
    public String name = "B";
}

public class Main {
    public static void main(String... args){
        B b = new B();
        System.out.println("Field from instance of class B pointed by reference to B : " + b.name);
        A a = b;
        System.out.println("Field from instance of class B pointed by reference to A : "+a.name);
        a.printMessage();
    }
}

печатает это:

Field from instance of class B pointed by reference to B : B
Field from instance of class B pointed by reference to A : A
Field accessed in method declared inside class A invoked form an object of class B : A

В отличие от свойств Kotlin - это поля, к которым обращаются автоматически созданные методы получения и установки.Свойства переопределяются (не скрываются), поэтому доступ к свойствам разрешается во время выполнения, и код со значением, аналогичным приведенному выше, написанным на Kotlin:

open class A {
    open val name = "A"
    fun printMessage() {
        println("Field accessed in method declared inside class A invoked form an object of $javaClass : $name")
    }
}

class B(override val name : String = "B") : A()

fun main(args : Array<String>) {
    val b : B = B()
    println("Field from instance of class B pointed by reference to B : " + b.name)
    val a : A = b;
    println("Field from instance of class B pointed by reference to A : " + a.name)
    a.printMessage()
}

печатает это:

Field from instance of class B pointed by reference to B : B 
Field from instance of class B pointed by reference to A : B 
Field accessed in method declared inside class A invoked form an object of class B : B

Уровень доступа
Поля Java по умолчанию являются пакетными.Свойства Kotlin являются общедоступными по умолчанию.

Инициализация по умолчанию
Поля Java инициализируются с приемлемыми значениями по умолчанию (как описано здесь: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html).

КаждыйСвойство класса Kotlin должно быть создано таким образом, чтобы оно могло предоставить явно заданное значение при доступе к нему. Этого можно добиться с помощью инициализатора, конструктора, сеттера, отложенной инициализации:

class InitValues(val inCtor : String = "Given in constructor"){
    var byInitializer = "In initializer"
    var initializedWithNull : String? = null
    val valueGivenByGetter
        get() : String {
            return "This value is given by getter"
        }
    val byLazyInit : String by lazy { "This is lazy init" }
}

, но с помощью значениято, что должно быть возвращено, должно быть дано - никакие значения по умолчанию предоставлены не будут.

Существуют ли какие-либо другие технические различия в отношении полей / свойств класса, которые могут удивить написание кода Java-программистом на Kotlin?

(IЯ не говорю о дополнительных функциях, таких как, например, делегированные свойства, но о тех вещах, которые на первый взгляд похожи на те, которые существуют в Java и могут быть обманчивыми)

...