Я начал изучать Котлин.Мой текущий опыт работы с 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 и могут быть обманчивыми)