Можно ли в файле kotlin прописать код на java
Kotlin is designed with Java interoperability in mind. Existing Java code can be called from Kotlin in a natural way, and Kotlin code can be used from Java rather smoothly as well. In this section, we describe some details about calling Java code from Kotlin.
Pretty much all Java code can be used without any issues:
import java.util.* fun demo(source: List
Null-safety and platform types
Any reference in Java may be null , which makes Kotlin's requirements of strict null-safety impractical for objects coming from Java. Types of Java declarations are treated in Kotlin in a specific manner and called platform types. Null-checks are relaxed for such types, so that safety guarantees for them are the same as in Java (see more below).
Consider the following examples:
val list = ArrayList
When you call methods on variables of platform types, Kotlin does not issue nullability errors at compile time, but the call may fail at runtime, because of a null-pointer exception or an assertion that Kotlin generates to prevent nulls from propagating:
Platform types are non-denotable, meaning that you can't write them down explicitly in the language. When a platform value is assigned to a Kotlin variable, you can rely on the type inference (the variable will have an inferred platform type then, as item has in the example above), or you can choose the type you expect (both nullable and non-null types are allowed):
val nullable: String? = item // allowed, always works val notNull: String = item // allowed, may fail at runtime
If you choose a non-null type, the compiler will emit an assertion upon assignment. This prevents Kotlin's non-null variables from holding nulls. Assertions are also emitted when you pass platform values to Kotlin functions expecting non-null values and in other cases. Overall, the compiler does its best to prevent nulls from propagating far through the program although sometimes this is impossible to eliminate entirely, because of generics.
Visibility
The Kotlin visibility modifiers map to Java in the following way:
private members are compiled to private members
private top-level declarations are compiled to package-local declarations
protected remains protected (note that Java allows accessing protected members from other classes in the same package and Kotlin doesn't, so Java classes will have broader access to the code)
internal declarations become public in Java. Members of internal classes go through name mangling, to make it harder to accidentally use them from Java and to allow overloading for members with the same signature that don't see each other according to Kotlin rules
public remains public
Java generics in Kotlin
Kotlin's generics are a little different from Java's (see Generics). When importing Java types to Kotlin we perform some conversions:
Java's wildcards are converted into type projections,
Java's raw types are converted into star projections,
Like Java's, Kotlin's generics are not retained at runtime, i.e. objects do not carry information about actual type arguments passed to their constructors, i.e. ArrayList() is indistinguishable from ArrayList() . This makes it impossible to perform is-checks that take generics into account. Kotlin only allows is-checks for star-projected generic types:
Null-safety
When calling Kotlin functions from Java, nobody prevents us from passing null as a non-null parameter. That's why Kotlin generates runtime checks for all public functions that expect non-nulls. This way we get a NullPointerException in the Java code immediately.
Во что может компилироваться и транслироваться Kotlin?
В Java-байткод и ES5.1, поддерживаемый модульными системами AMD and CommonJS. Скоро появится возможность компилировать в код для конкретной платформы с LLVM.
Notation for platform types
As mentioned above, platform types can't be mentioned explicitly in the program, so there's no syntax for them in the language. Nevertheless, the compiler and IDE need to display them sometimes (for example, in error messages or parameter info), so there is a mnemonic notation for them:
T! means " T or T? ",
(Mutable)Collection! means "Java collection of T may be mutable or not, may be nullable or not",
Array! means "Java array of T (or a subtype of T ), nullable or not"
Checked exceptions
Kotlin does not have checked exceptions. So, normally the Java signatures of Kotlin functions do not declare exceptions thrown. Thus, if you have a function in Kotlin like this:
And you want to call it from Java and catch the exception:
You get an error message from the Java compiler, because writeToFile() does not declare IOException . To work around this problem, use the @Throws annotation in Kotlin:
Есть ли сообщество у Kotlin?
Да. У Kotlin очень отзывчивое сообщество на форумах Kotlin, StackOverflow и, наиболее активно, Kotlin Slack (примерно 7000 участников в мае 2017).
Есть ли онлайн-курсы для изучения Kotlin?
Pluralsight Kotlin Course от Кевина Джонса, курс O’Reilly от Хади Харири и курс Udemy от Петра Соммерхоффа.
Также есть множество записей Kotlin talks, которые можно найти на YouTube и Vimeo.
Какие компании используют Kotlin?
Kotlin используют множество компаний. Из числа тех, что обьявили об использовании языка: Square, Pinterest, Basecamp и Corda.
Аннотации допустимости null значений
Типы Java, которые имеют аннотации допустимости null-значений представлены не как платформенные типы, а как реальные nullable или non-null типы Kotlin. Компилятор поддерживает несколько стандартов аннотаций, включая:
-
( @Nullable и @NotNull из пакета org.jetbrains.annotations )
- Android ( com.android.annotations и android.support.annotations )
- JSR-305 ( javax.annotation , подробности смотрите ниже)
- FindBugs ( edu.umd.cs.findbugs.annotations )
- Eclipse ( org.eclipse.jdt.annotation )
- Lombok ( lombok.NonNull ).
Mapped types
Kotlin treats some Java types specially. Such types are not loaded from Java "as is", but are mapped to corresponding Kotlin types. The mapping only matters at compile time, the runtime representation remains unchanged. Java's primitive types are mapped to corresponding Kotlin types (keeping platform types in mind):
Some non-primitive built-in classes are also mapped:
Java's boxed primitive types are mapped to nullable Kotlin types:
Note that a boxed primitive type used as a type parameter is mapped to a platform type: for example, List becomes a List in Kotlin.
Collection types may be read-only or mutable in Kotlin, so Java's collections are mapped as follows (all Kotlin types in this table reside in the package kotlin.collections ):
Java type | Kotlin read-only type | Kotlin mutable type | Loaded platform type |
---|---|---|---|
Iterator | Iterator | MutableIterator | (Mutable)Iterator! |
Iterable | Iterable | MutableIterable | (Mutable)Iterable! |
Collection | Collection | MutableCollection | (Mutable)Collection! |
Set | Set | MutableSet | (Mutable)Set! |
List | List | MutableList | (Mutable)List! |
ListIterator | ListIterator | MutableListIterator | (Mutable)ListIterator! |
Map | Map | MutableMap | (Mutable)Map! |
Map.Entry | Map.Entry | MutableMap.MutableEntry | (Mutable)Map.(Mutable)Entry! |
Java's arrays are mapped as mentioned below:
Java type | Kotlin type |
---|---|
int[] | kotlin.IntArray! |
String[] | kotlin.Array! |
Instance fields
If you need to expose a Kotlin property as a field in Java, annotate it with the @JvmField annotation. The field will have the same visibility as the underlying property. You can annotate a property with @JvmField if it:
has a backing field
does not have open , override or const modifiers
is not a delegated property
Late-Initialized properties are also exposed as fields. The visibility of the field will be the same as the visibility of lateinit property setter.
KClass
Sometimes you need to call a Kotlin method with a parameter of type KClass . There is no automatic conversion from Class to KClass , so you have to do it manually by invoking the equivalent of the Class.kotlin extension property:
KClass
Иногда вам нужно вызвать метод Kotlin с параметром типа KClass . Автоматического преобразования из Class в KClass нет, поэтому вам нужно сделать это вручную, вызывая эквивалент свойства расширения Class.kotlin :
.kotlin` extension property: ```kotlin kotlin.jvm.JvmClassMappingKt.getKotlinClass(MainView.class) ``` -->
Overloads generation
Normally, if you write a Kotlin function with default parameter values, it will be visible in Java only as a full signature, with all parameters present. If you wish to expose multiple overloads to Java callers, you can use the @JvmOverloads annotation.
The annotation also works for constructors, static methods, and so on. It can't be used on abstract methods, including methods defined in interfaces.
For every parameter with a default value, this will generate one additional overload, which has this parameter and all parameters to the right of it in the parameter list removed. In this example, the following will be generated:
// Constructors: Circle(int centerX, int centerY, double radius) Circle(int centerX, int centerY) // Methods void draw(String label, int lineWidth, String color) < >void draw(String label, int lineWidth) < >void draw(String label) < >
Note that, as described in Secondary constructors, if a class has default values for all constructor parameters, a public constructor with no arguments will be generated for it. This works even if the @JvmOverloads annotation is not specified.
Java Reflection
Java reflection works on Kotlin classes and vice versa. As mentioned above, you can use instance::class.java , ClassName::class.java or instance.javaClass to enter Java reflection through java.lang.Class .
Other supported cases include acquiring a Java getter/setter method or a backing field for a Kotlin property, a KProperty for a Java field, a Java method or constructor for a KFunction and vice versa.
JSR-305 support
The @Nonnull annotation defined in JSR-305 is supported for denoting nullability of Java types.
If the @Nonnull(when = . ) value is When.ALWAYS , the annotated type is treated as non-null; When.MAYBE and When.NEVER denote a nullable type; and When.UNKNOWN forces the type to be platform one.
A library can be compiled against the JSR-305 annotations, but there's no need to make the annotations artifact (e.g. jsr305.jar ) a compile dependency for the library consumers. The Kotlin compiler can read the JSR-305 annotations from a library without the annotations present on the classpath.
Type qualifier nicknames
If an annotation type is annotated with both @TypeQualifierNickname and JSR-305 @Nonnull (or its another nickname, such as @CheckForNull ), then the annotation type is itself used for retrieving precise nullability and has the same meaning as that nullability annotation:
Type qualifier defaults
@TypeQualifierDefault allows introducing annotations that, when being applied, define the default nullability within the scope of the annotated element.
Such annotation type should itself be annotated with both @Nonnull (or its nickname) and @TypeQualifierDefault(. ) with one or more ElementType values:
ElementType.METHOD for return types of methods
ElementType.PARAMETER for value parameters
ElementType.FIELD for fields
ElementType.TYPE_USE for any type including type arguments, upper bounds of type parameters and wildcard types
The default nullability is used when a type itself is not annotated by a nullability annotation, and the default is determined by the innermost enclosing element annotated with a type qualifier default annotation with the ElementType matching the type usage.
@Nonnull @TypeQualifierDefault(
The types in this example only take place with the strict mode enabled; otherwise, the platform types remain. See the @UnderMigration annotation and Compiler configuration sections.
Package-level default nullability is also supported:
// FILE: test/package-info.java @NonNullApi // declaring all types in package 'test' as non-nullable by default package test;
@UnderMigration annotation
The @UnderMigration annotation (provided in a separate artifact kotlin-annotations-jvm ) can be used by library maintainers to define the migration status for the nullability type qualifiers.
The status value in @UnderMigration(status = . ) specifies how the compiler treats inappropriate usages of the annotated types in Kotlin (e.g. using a @MyNullable -annotated type value as non-null):
MigrationStatus.STRICT makes annotation work as any plain nullability annotation, i.e. report errors for the inappropriate usages and affect the types in the annotated declarations as they are seen in Kotlin
MigrationStatus.WARN : the inappropriate usages are reported as compilation warnings instead of errors, but the types in the annotated declarations remain platform
MigrationStatus.IGNORE makes the compiler ignore the nullability annotation completely
A library maintainer can add @UnderMigration status to both type qualifier nicknames and type qualifier defaults:
@Nonnull(when = When.ALWAYS) @TypeQualifierDefault(
The migration status of a nullability annotation is not inherited by its type qualifier nicknames but is applied to its usages in default type qualifiers.
If a default type qualifier uses a type qualifier nickname and they are both @UnderMigration , the status from the default type qualifier is used.
Compiler configuration
The JSR-305 checks can be configured by adding the -Xjsr305 compiler flag with the following options (and their combination):
-Xjsr305=
-Xjsr305=under-migration:
-Xjsr305=@:
The strict , warn and ignore values have the same meaning as those of MigrationStatus , and only the strict mode affects the types in the annotated declarations as they are seen in Kotlin.
Note: the built-in JSR-305 annotations @Nonnull , @Nullable and @CheckForNull are always enabled and affect the types of the annotated declarations in Kotlin, regardless of compiler configuration with the -Xjsr305 flag.
For example, adding -Xjsr305=ignore -Xjsr305=under-migration:ignore -Xjsr305=@org.library.MyNullable:warn to the compiler arguments makes the compiler generate warnings for inappropriate usages of types annotated by @org.library.MyNullable and ignore all other JSR-305 annotations.
The default behavior is the same to -Xjsr305=warn . The strict value should be considered experimental (more checks may be added to it in the future).
Escaping for Java identifiers that are keywords in Kotlin
Some of the Kotlin keywords are valid identifiers in Java: in , object , is , and other. If a Java library uses a Kotlin keyword for a method, you can still call the method escaping it with the backtick (`) character:
Nullability annotations
Java types that have nullability annotations are represented not as platform types, but as actual nullable or non-null Kotlin types. The compiler supports several flavors of nullability annotations, including:
JetBrains ( @Nullable and @NotNull from the org.jetbrains.annotations package)
Android ( com.android.annotations and android.support.annotations )
JSR-305 ( javax.annotation , more details below)
RxJava 3 ( io.reactivex.rxjava3.annotations )
You can specify whether the compiler reports a nullability mismatch based on the information from specific types of nullability annotations. Use the compiler option -Xnullability-annotations=@: . In the argument, specify the fully qualified nullability annotations package and one of these report levels:
ignore to ignore nullability mismatches
warn to report warnings
strict to report errors.
See the full list of supported nullability annotations in the Kotlin compiler source code.
Для чего я могу использовать Kotlin?
Kotlin может быть использован для разработки для множества платформ, будь то сервер, клиент, веб или Android. C релизом Kotlin/Native (который на текущий момент в разработке) появится поддержка таких платформ, как встроенные системы, macOS и iOS. Люди используют Kotlin для мобильных и серверных приложений, клиентских приложений с JavaScript или JavaFX, в data science и так далее.
Package-level functions
All the functions and properties declared in a file app.kt inside a package org.example , including extension functions, are compiled into static methods of a Java class named org.example.AppKt .
To set a custom name to the generated Java class, use the @JvmName annotation:
Having multiple files with the same generated Java class name (the same package and the same name or the same @JvmName annotation) is normally an error. However, the compiler can generate a single Java facade class which has the specified name and contains all the declarations from all the files which have that name. To enable the generation of such a facade, use the @JvmMultifileClass annotation in all such files.
Есть ли ещё какие-либо онлайн-ресурсы по Kotlin?
В сообществе Kotlin вы можете найти множество ресурсов, включая Дайджесты Kotlin, организуемые сообществом, новостную рассылку, подкаст и так далее.
Свойство Kotlin компилируется в следующие Java элементы:
- Метод getter, имя которого вычисляется путем добавления префикса get ;
- Метод setter, имя которого вычисляется путем добавления префикса set (только для свойств var );
- Приватное поле с тем же именем, что и имя свойства (только для свойств с backing fields).
Например, var firstName: String компилируется в следующие объявления Java:
Если имя свойства начинается с is , используется другое правило сопоставления имен: имя метода getter будет совпадать с именем свойства, а имя метода setter будет получено путем замены is на set . Например, для свойства isOpen , getter будет называться isOpen() и setter будет называться setOpen() . Это правило применяется к свойствам любого типа, а не только к Boolean .
Static fields
Kotlin properties declared in a named object or a companion object will have static backing fields either in that named object or in the class containing the companion object.
Usually these fields are private but they can be exposed in one of the following ways:
Annotating such a property with @JvmField makes it a static field with the same visibility as the property itself.
A late-initialized property in an object or a companion object has a static backing field with the same visibility as the property setter.
Properties declared as const (in classes as well as at the top level) are turned into static fields in Java:
Есть ли Kotlin в социальных сетях?
Наиболее активный аккаунт на Twitter. Также есть группа Google+.
Accessing static members
Static members of Java classes form "companion objects" for these classes. We cannot pass such a "companion object" around as a value, but can access the members explicitly, for example:
Методы возвращающие void
Если метод Java возвращает void, он вернет Unit при вызове из Kotlin. Если по какой-либо причине кто-либо использует данный тип в своих целях, он будет присвоен в месте вызова компилятором Kotlin, так как значение само по себе известно заранее (являясь Unit ).
Null-безопасность и платформенные типы
Любая ссылка в Java может прнимать значение null, что делает требования Kotlin по null-safety непрактичными для объектов приходящих из Java. Типы, декларируемые в Java обрабатываются по-особому в Kotlin и называются платформенными типами. Null-проверки для таких типов являются менее строгими, таким образом безопасность для них гарантирована таким же образом, как и в Java (подробнее смотрите ниже).
Рассмотрим следующие примеры:
Когда мы вызываем методы на переменных платформенных типов, Kotlin не обрабатывает ошибки отсутствия значения во время компиляции, но работа этих методов может вызвать ошибки на рантайме по причине NPE либо ассершена, генерируемого Kotlin для предотвращения всплытия null значений:
Платформенные типы являются необозначаемыми, что значит, что их нельзя объявить непосредственно в языке. Когда платформенное значение присваивается переменной в Kotlin, мы можем полагаться на автоматическое определение типа (переменная получит подразумеваемый платформенный тип, так же как item приведенная в примерах выше), или же мы можем сами выбрать ожидаемый тип (разрешаются как nullable, так и non-null типы):
Если мы выбираем non-null тип, компилятор выбросит ассершен при присвоении значения. Это предотвратит non-null переменные Kotlin от хранения null-значений. Ассершены так же выбрасываются, когда мы передаем платформенные значения в функции Kotlin, ожидающие non-null значения. В целом, компилятор делает все возможное для предотвращения всплытия null-значений в глубине программы (и все же иногда возникают проблемы при использовании дженериков).
Static methods
As mentioned above, Kotlin represents package-level functions as static methods. Kotlin can also generate static methods for functions defined in named objects or companion objects if you annotate those functions as @JvmStatic . If you use this annotation, the compiler will generate both a static method in the enclosing class of the object and an instance method in the object itself. For example:
Now, callStatic() is static in Java while callNonStatic() is not:
Same for named objects:
Obj.callStatic(); // works fine Obj.callNonStatic(); // error Obj.INSTANCE.callNonStatic(); // works, a call through the singleton instance Obj.INSTANCE.callStatic(); // works too
Starting from Kotlin 1.3, @JvmStatic applies to functions defined in companion objects of interfaces as well. Such functions compile to static methods in interfaces. Note that static method in interfaces were introduced in Java 1.8, so be sure to use the corresponding targets.
@JvmStatic annotation can also be applied on a property of an object or a companion object making its getter and setter methods static members in that object or the class containing the companion object.
clone()
To override clone() , your class needs to extend kotlin.Cloneable :
Do not forget about Effective Java, Item 11: Override clone judiciously.
Обработка столкновений сигнатур с @JvmName
Иногда у нас есть именованная функция в Kotlin, для которой нам нужно другое JVM-имя байтового кода. Самый яркий пример происходит вследствии стирания типа:
Эти две функции не могут быть определены вместе, потому что их подписи JVM одинаковы: filterValid(Ljava/util/List;)Ljava/util/List; . Если мы действительно хотим, чтобы они имели одно и то же имя в Kotlin, мы можем добавить одному (или обоим) аннотацию @JvmName и указать другое имя в качестве аргумента:
Из Kotlin они будут доступны с одинаковым именем filterValid , но из Java это будет filterValid и filterValidInt .
Этот же трюк применяется, когда нам нужно иметь свойство x вместе с функцией getX() :
Чтобы изменить имена созданных методов доступа для свойств без явно введенных геттеров и сеттеров, вы можете использовать @get:JvmName и @set:JvmName :
.filterValid(): List fun List .filterValid(): List ``` These two functions can not be defined side-by-side, because their JVM signatures are the same: `filterValid(Ljava/util/List;)Ljava/util/List;`. If we really want them to have the same name in Kotlin, we can annotate one (or both) of them with `@JvmName` and specify a different name as an argument: ```kotlin fun List .filterValid(): List @JvmName("filterValidInt") fun List .filterValid(): List ``` From Kotlin they will be accessible by the same name `filterValid`, but from Java it will be `filterValid` and `filterValidInt`. The same trick applies when we need to have a property `x` alongside with a function `getX()`: ```kotlin val x: Int @JvmName("getX_prop") get() = 15 fun getX() = 10 ``` To change the names of generated accessor methods for properties without explicitly implemented getters and setters, you can use `@get:JvmName` and `@set:JvmName`: ```kotlin @get:JvmName("x") @set:JvmName("changeX") var x: Int = 23 ``` -->
Methods returning void
If a Java method returns void , it will return Unit when called from Kotlin. If by any chance someone uses that return value, it will be assigned at the call site by the Kotlin compiler since the value itself is known in advance (being Unit ).
getClass()
To retrieve the Java class of an object, use the java extension property on a class reference:
The code above uses a bound class reference, which is supported since Kotlin 1.1. You can also use the javaClass extension property:
Сложен ли Kotlin?
Видимость (Visibility)
Видимость в Kotlin представляется в Java следующим образом:
- private элементы компилируются в private элементы;
- private объявления верхнего уровня компилируются в локальные объявления пакетов;
- protected остаются protected (обратите внимание, что java разрешает доступ к защищенным членам из других классов в том же пакете, а Kotlin-нет, поэтому классы Java будут иметь более широкий доступ к коду);
- internal объявления становятся public в JAVA. Члены internal классов проходят через искажение имен, чтобы усложнить случайное использование их из Java и позволить перегрузку для членов с одинаковыми сигнатурами, которые не видят друг друга в соответствии с правилами Kotlin;
- public остаются public .
Поддержка JSR-305
Аннотация @Nonnull объявленная в JSR-305 поддерживается для использования с типами Java.
If the @Nonnull(when = . ) value is When.ALWAYS , the annotated type is treated as non-null; When.MAYBE and When.NEVER denote a nullable type; and When.UNKNOWN forces the type to be platform one.
A library can be compiled against the JSR-305 annotations, but there's no need to make the annotations artifact (e.g. jsr305.jar ) a compile dependency for the library consumers. The Kotlin compiler can read the JSR-305 annotations from a library without the annotations present on the classpath.
Начиная с версии Kotlin 1.1.50, custom nullability qualifiers (KEEP-79) are also supported (see below).
Type qualifier nicknames (since 1.1.50)
If an annotation type is annotated with both @TypeQualifierNickname and JSR-305 @Nonnull (or its another nickname, such as @CheckForNull ), then the annotation type is itself used for retrieving precise nullability and has the same meaning as that nullability annotation:
Type qualifier defaults (since 1.1.50)
@TypeQualifierDefault allows introducing annotations that, when being applied, define the default nullability within the scope of the annotated element.
Such annotation type should itself be annotated with both @Nonnull (or its nickname) and @TypeQualifierDefault(. ) with one or more ElementType values:
- ElementType.METHOD for return types of methods;
- ElementType.PARAMETER for value parameters;
- ElementType.FIELD for fields; and
- ElementType.TYPE_USE (since 1.1.60) for any type including type arguments, upper bounds of type parameters and wildcard types.
The default nullability is used when a type itself is not annotated by a nullability annotation, and the default is determined by the innermost enclosing element annotated with a type qualifier default annotation with the ElementType matching the type usage.
Note: the types in this example only take place with the strict mode enabled, otherwise, the platform types remain. See the @UnderMigration annotation and Compiler configuration sections.
Package-level default nullability is also supported:
@UnderMigration annotation (since 1.1.60)
The @UnderMigration annotation (provided in a separate artifact kotlin-annotations-jvm ) can be used by library maintainers to define the migration status for the nullability type qualifiers.
The status value in @UnderMigration(status = . ) specifies how the compiler treats inappropriate usages of the annotated types in Kotlin (e.g. using a @MyNullable -annotated type value as non-null):
MigrationStatus.STRICT makes annotation work as any plain nullability annotation, i.e. report errors for the inappropriate usages and affect the types in the annotated declarations as they are seen in Kotlin;
with MigrationStatus.WARN , the inappropriate usages are reported as compilation warnings instead of errors, but the types in the annotated declarations remain platform; and
MigrationStatus.IGNORE makes the compiler ignore the nullability annotation completely.
A library maintainer can add @UnderMigration status to both type qualifier nicknames and type qualifier defaults:
Note: the migration status of a nullability annotation is not inherited by its type qualifier nicknames but is applied to its usages in default type qualifiers.
If a default type qualifier uses a type qualifier nickname and they are both @UnderMigration , the status from the default type qualifier is used.
Compiler configuration
The JSR-305 checks can be configured by adding the -Xjsr305 compiler flag with the following options (and their combination):
-Xjsr305=
-Xjsr305=under-migration:
-Xjsr305=@:
The strict , warn and ignore values have the same meaning as those of MigrationStatus , and only the strict mode affects the types in the annotated declarations as they are seen in Kotlin.
Note: the built-in JSR-305 annotations @Nonnull , @Nullable and @CheckForNull are always enabled and affect the types of the annotated declarations in Kotlin, regardless of compiler configuration with the -Xjsr305 flag.
For example, adding -Xjsr305=ignore -Xjsr305=under-migration:ignore -Xjsr305=@org.library.MyNullable:warn to the compiler arguments makes the compiler generate warnings for inappropriate usages of types annotated by @org.library.MyNullable and ignore all other JSR-305 annotations.
For kotlin versions 1.1.50+/1.2, the default behavior is the same to -Xjsr305=warn . The strict value should be considered experimental (more checks may be added to it in the future).
Экранирование идентификаторов Java совпадающих с ключевыми словами Kotlin
Некоторые из ключевых слов Kotlin являются валидными идентификаторами в Java: in, object, is, и т.д. Если Java-библиотека использует ключевые слова Kotlin в названиях методов, вы все еще можете вызывать метод используя экранирование с помощью обратной кавычки (`):
Java Varargs
Java classes sometimes use a method declaration for the indices with a variable number of arguments (varargs):
In that case you need to use the spread operator * to pass the IntArray :
It's currently not possible to pass null to a method that is declared as varargs.
Можно ли использовать Kotlin для разработки для Android?
Можно. Kotlin поддерживается как основной язык для Android, наравне с Java. Сотни приложений для Android уже используют Kotlin, к примеру Basecamp, Pinterest и так далее. Чтобы узнать больше, смотрите статью про разработку для Android.
Какие инструменты для сборки поддерживают Kotlin?
На стороне JVM - Gradle, Maven, Ant и Kobalt. Также есть множество инструментов со стороны JavaScript.
Проверенные исключения (Checked Exceptions)
Как мы уже упоминали выше, Котлин не имеет проверенных исключений. Таким образом, как правило, сигнатуры Java функций Kotlin не объявляют исключения. Поэтому если мы имеем такую функцию в Котлине:
И мы хотим вызвать её из Java и поймать исключение:
Перевод типа Nothing (Translation of type Nothing)
Тип Nothing является особым, потому что он не имеет естественного аналога на Java. Действительно, каждый ссылочный тип Java, включая java.lang.Void , принимает значение null как значение, а Nothing не принимает даже этого. Таким образом, этот тип не может быть точно представлен в Java-мире. Вот почему Kotlin генерирует необработанный тип, где аргумент типа Nothing используется:
Kotlin изначально проектировался с учетом необходимости взаимодействия с языком Java. Существующий код Java может быть вызван из Kotlin естественным способом, также как и код на Kotlin может быть использован в Java без особых проблем. В этом разделе мы опишем некоторые детали о вызове кода Java из Kotlin.
Почти любой код Java может быть использован без особых проблем:
SAM Преобразования
Как и Java 8, Kotlin поддерживает SAM (Single Abstract Method) преобразования. Это означает, что литералы функций в Kotlin могут быть автоматически преобразованы к реализации Java интерфейсов с одним абстрактным методом, если типы параметров функции в Kotlin совпадают с типами параметров метода интерфеса.
Вы можете использовать это для создания объектов SAM интерфейсов:
. и в вызовах метода:
Если Java класс имеет несколько методов, принимающих функциональные интерфейсы, Вы можете выбрать тот, который Вам нужен, используя адаптер функции, который преобразует лямбду в необходимый SAM тип. Эти адаптеры также генерируются компилятором, когда это необходимо:
Обратите внимание, что SAM преобразования работают только для интерфейсов, не для абстрактных классов, даже если у них всего один абстрактный метод.
Также обратите внимание, что SAM преобразования работают только для Java совместимости; поскольку в Kotlin есть функциональные типы, автоматическое преобразование функий в реализацию Kotlin интерфейсов не требуется, поэтому не поддерживается.
Kotlin поддерживает лишь Java 6?
Не только. Вы можете выбирать между байткодом 6 или 8 версии. Чем новее версия Java, тем лучше и эффективнее байткод.
Properties
A Kotlin property is compiled to the following Java elements:
a getter method, with the name calculated by prepending the get prefix
a setter method, with the name calculated by prepending the set prefix (only for var properties)
a private field, with the same name as the property name (only for properties with backing fields)
For example, var firstName: String compiles to the following Java declarations:
If the name of the property starts with is , a different name mapping rule is used: the name of the getter will be the same as the property name, and the name of the setter will be obtained by replacing is with set . For example, for a property isOpen , the getter will be called isOpen() and the setter will be called setOpen() . This rule applies for properties of any type, not just Boolean .
Можно ли использовать Kotlin для разработки Desktop-приложений?
Да. Вы можете использовать любой UI-фреймворк, например JavaFx, Swing и т.д. В добавок, существуют фреймворки для Kotlin, такие как TornadoFX.
Можно ли использовать Kotlin для разработки серверных приложений?
Можно. Kotlin на 100% совместим с JVM, а значит вы можете использовать любые фреймворки для Java, такие как Spring Boot, vert.x или JSF. Также есть фреймворки для Kotlin, как например Ktor. Смотрите статью о разработке серверных приложений.
finalize()
To override finalize() , all you need to do is simply declare it, without using the override keyword:
According to Java's rules, finalize() must not be private.
Java Arrays
Arrays in Kotlin are invariant, unlike Java. This means that Kotlin does not let us assign an Array to an Array , which prevents a possible runtime failure. Passing an array of a subclass as an array of superclass to a Kotlin method is also prohibited, but for Java methods this is allowed (through platform types of the form Array! ).
Arrays are used with primitive datatypes on the Java platform to avoid the cost of boxing/unboxing operations. As Kotlin hides those implementation details, a workaround is required to interface with Java code. There are specialized classes for every type of primitive array ( IntArray , DoubleArray , CharArray , and so on) to handle this case. They are not related to the Array class and are compiled down to Java's primitive arrays for maximum performance.
Suppose there is a Java method that accepts an int array of indices:
To pass an array of primitive values you can do the following in Kotlin:
При компиляции в байт-код JVM, компилятор оптимизирует доступ к массивам, таким образом, что отсутствуют какие-либо накладные расходы:
Even when we navigate with an index, it does not introduce any overhead:
Finally, in-checks have no overhead either:
Какова текущая версия Kotlin?
Последняя выпущенная версия - 1.5.10, опубликована 24 мая 2021 г.
Является ли Kotlin обьектно-ориентированным или функциональным?
Kotlin является и тем, и другим. Вы можете как угодно использовать и комбинировать эти стили. При полной поддержке таких возможностей, как функции высшего порядка, функциональные типы и лямбда-выражения, Kotlin - отличный выбор, если вы используете или изучаете функциональное программирование.
Mapped types
Kotlin treats some Java types specifically. Such types are not loaded from Java "as is", but are mapped to corresponding Kotlin types. The mapping only matters at compile time, the runtime representation remains unchanged. Java's primitive types are mapped to corresponding Kotlin types (keeping platform types in mind):
Kotlin - OSS-статически типизированный язык программирования с поддержкой JVM, Android, JavaScript и Native. Язык разработан JetBrains. Проект начался в 2010 и с самого начала был открытым. Версия 1.0 была выпущена в феврале 2016 г.
Проходят ли конференции, посвящённые Kotlin?
Да. Первая официальная конференция - KotlinConf - прошла в Сан-Франциско со 2 по 3 ноября 2017 года. Kotlin также обсуждается во время различных конференций по всему миру. Вы можете найти список ближайших конференций на этом сайте.
Какие IDE поддерживают Kotlin?
Kotlin поддерживается всеми крупными IDE для Java, включая IntelliJ IDEA, Android Studio, Eclipse и NetBeans. Также доступен отдельный компилятор, полностью поддерживающий все возможности компиляции и запуска приложений.
Функции уровня пакета (Package-Level Functions)
Все функции и свойства, объявленные в файле example.kt внутри пакета org.foo.bar , включая функции расширения, скомпилированы в статические методы класса Java с именем org.foo.bar.ExampleKt .
Имя генерируемого JAVA класса может быть выбранно при помощи аннотации @JvmName :
Наличие нескольких файлов, имеющих одинаковое имя Java-класса (тот же пакет и одинаковое имя или аннотацию @JvmName ), является ошибкой. Однако компилятор имеет возможность генерировать один Java класс фасада, который имеет указанное имя и содержит все объявления из всех файлов, которые имеют такое имя. Чтобы включить генерацию такого фасада, используйте аннотацию @JvmMultifileClass во всех файлах.
Variant generics
Когда классы Kotlin используют вариативность на уровне объявления, есть два варианта того, как их использование видно из кода Java. Допустим, у нас есть следующий класс и две функции, которые его используют:
Наивный способ перевести эти функции в Java будет
Проблема в том, что в Kotlin мы можем сказать unboxBase(boxDerived ("s")) , но в Java это было бы невозможно, потому что в Java класс Box является инвариантным по своему параметру T и, следовательно, Box не является подтипом Box . Чтобы заставить его работать на Java, нам нужно определить unboxBase следующим образом:
Здесь мы используем типы подстановок Java ( ? extends Base ), чтобы эмулировать вариативность на уровне объявления с помощью вариативности на уровне употребления, потому что она имеется в Java.
Чтобы заставить API Kotlin работать в Java, мы генерируем Box как Box для ковариантно определенных Box (или Foo для контравариантно определенных Foo ), когда он появляется как параметр. Когда это возвращаемое значение, мы не создаем подстановочные знаки, потому что в противном случае клиенты Java будут иметь дело с ними (а это противоречит общему стилю кодирования Java). Поэтому функции из нашего примера фактически переводятся следующим образом:
ПРИМЕЧАНИЕ. Когда тип аргумента является окончательным, обычно нет смысла создавать подстановочный знак, поэтому Box всегда Box , независимо от того, какую позицию он занимает.
Если нам нужны подстановочные знаки, где они не генерируются по умолчанию, мы можем использовать аннотацию @JvmWildcard :
С другой стороны, если нам не нужны подстановочные знаки, где они созданы, мы можем использовать @JvmSuppressWildcards :
ПРИМЕЧАНИЕ. @JvmSuppressWildcards можно использовать не только для индивидуальных аргументов типа, но и для всех объявлений, таких как функции или классы, что приводит к подавлению всех подстановочных знаков внутри них.
(val value: T) interface Base class Derived : Base fun boxDerived(value: Derived): Box = Box(value) fun unboxBase(box: Box ): Base = box.value ``` A naive way of translating these functions into Java would be this: ``` java Box boxDerived(Derived value) < . >Base unboxBase(Box box) < . >``` The problem is that in Kotlin we can say `unboxBase(boxDerived("s"))`, but in Java that would be impossible, because in Java the class `Box` is *invariant* in its parameter `T`, and thus `Box ` is not a subtype of `Box `. To make it work in Java we'd have to define `unboxBase` as follows: ``` java Base unboxBase(Box box) < . >``` Here we make use of Java's *wildcards types* (`? extends Base`) to emulate declaration-site variance through use-site variance, because it is all Java has. To make Kotlin APIs work in Java we generate `Box ` as `Box ` for covariantly defined `Box` (or `Foo ` for contravariantly defined `Foo`) when it appears *as a parameter*. When it's a return value, we don't generate wildcards, because otherwise Java clients will have to deal with them (and it's against the common Java coding style). Therefore, the functions from our example are actually translated as follows: ``` java // return type - no wildcards Box boxDerived(Derived value) < . >// parameter - wildcards Base unboxBase(Box box) < . >``` NOTE: when the argument type is final, there's usually no point in generating the wildcard, so `Box ` is always `Box `, no matter what position it takes. If we need wildcards where they are not generated by default, we can use the `@JvmWildcard` annotation: ```kotlin fun boxDerived(value: Derived): Box = Box(value) // is translated to // Box boxDerived(Derived value) < . >``` On the other hand, if we don't need wildcards where they are generated, we can use `@JvmSuppressWildcards`: ```kotlin fun unboxBase(box: Box ): Base = box.value // is translated to // Base unboxBase(Box box) < . >``` NOTE: `@JvmSuppressWildcards` can be used not only on individual type arguments, but on entire declarations, such as functions or classes, causing all wildcards inside them to be suppressed. -->
Генерация перегрузок
Обычно, если вы пишете функцию Kotlin со значениями параметров по умолчанию, она будет видна в Java только как полная сигнатура со всеми параметрами. Если вы хотите предоставить многократные перегрузки вызовам Java, можно использовать аннотацию @JvmOverloads .
Аннотации также работают для конструкторов, статических методов и т.д. Их нельзя использовать для абстрактных методов, включая методы, определенные в интерфейсах.
Для каждого параметра со значением по умолчанию это создаст одну дополнительную перегрузку, которая имеет этот параметр и все параметры справа от него в удаленном списке параметров. В этом примере будет создано следующее:
Обратите внимание, как описаны вторичные конструкторы, если класс имеет значения по умолчанию для всех параметров конструктора, то для него будет создан открытый конструктор без аргументов. Это работает, даже если не указана аннотация @JvmOverloads .
Можно ли использовать Kotlin для нативной разработки?
Kotlin/Native в текущий момент в разработке. Kotlin/Native позволит компилировать исходный код в нативный, который может работать без виртуальной машины. На данный момент готова технологическая демо-версия, но она еще не готова к продакшену и не поддерживает некоторые платформы, которые запланированы к версии 1.0. Смотрите пост, анонсирующий Kotlin/Native.
Статические поля (Static Fields)
Свойства Kotlin, объявленные в именованном объекте или объекте-помощнике, будут иметь статические backing fields в этом именованном объекте или в классе, содержащем объект-помощник.
Обычно эти поля являются приватными, но они могут быть представлены одним из следующих способов:
- @JvmField аннотацией;
- lateinit модификатором;
- const модификатором.
Аннотирование такого свойства с помощью @JvmField делает его статическим полем с той же видимостью, что и само свойство.
Свойство с поздней инициализацией в объекте или объекте-помощнике имеет статическое backing field с той же видимостью, что и сеттер свойства.
Свойства, аннотированные const (как в классах, так и на верхнем уровне), превращаются в статические поля в Java:
Проверяемые (checked) исключения
В Kotlin все исключения непроверяемые (unchecked), это значит, что компилятор не будет заставлять Вас их обрабатывать. Так, когда Вы вызываете Java метод, который может выбросить проверяемое (checked) исключение, Kotlin не заставит Вас его обработать:
Handling signature clashes with @JvmName
Sometimes we have a named function in Kotlin, for which we need a different JVM name in the bytecode. The most prominent example happens due to type erasure:
These two functions can not be defined side-by-side, because their JVM signatures are the same: filterValid(Ljava/util/List;)Ljava/util/List; . If we really want them to have the same name in Kotlin, we can annotate one (or both) of them with @JvmName and specify a different name as an argument:
From Kotlin they will be accessible by the same name filterValid , but from Java it will be filterValid and filterValidInt .
The same trick applies when we need to have a property x alongside with a function getX() :
To change the names of generated accessor methods for properties without explicitly implemented getters and setters, you can use @get:JvmName and @set:JvmName :
Annotating type arguments and type parameters
You can annotate the type arguments and type parameters of generic types to provide nullability information for them as well.
All examples in the section use JetBrains nullability annotations from the org.jetbrains.annotations package.
Type arguments
Consider these annotations on a Java declaration:
They result in the following signature in Kotlin:
When the @NotNull annotation is missing from a type argument, you get a platform type instead:
Kotlin also takes into account nullability annotations on type arguments of base classes and interfaces. For example, there are two Java classes with the signatures provided below:
In the Kotlin code, passing the instance of Derived where the Base is assumed produces the warning.
The upper bound of Derived is set to Base , which is different from Base .
Type parameters
By default, the nullability of plain type parameters in both Kotlin and Java is undefined. In Java, you can specify it using nullability annotations. Let's annotate the type parameter of the Base class:
When inheriting from Base , Kotlin expects a non-nullable type argument or type parameter. Thus, the following Kotlin code produces a warning:
You can fix it by specifying the upper bound K : Any .
Kotlin also supports nullability annotations on the bounds of Java type parameters. Let's add bounds to Base :
Kotlin translates this just as follows:
So passing nullable type as a type argument or type parameter produces a warning.
Annotating type arguments and type parameters works with the Java 8 target or higher. The feature requires that the nullability annotations support the TYPE_USE target ( org.jetbrains.annotations supports this in version 15 and above). Pass the -Xtype-enhancement-improvements-strict-mode compiler option to report errors in Kotlin code that uses nullability which deviates from the nullability annotations from Java.
Note: If a nullability annotation supports other targets that are applicable to a type in addition to the TYPE_USE target, then TYPE_USE takes priority. For example, if @Nullable has both TYPE_USE and METHOD targets, the Java method signature @Nullable String[] f() becomes fun f(): Array! in Kotlin.
Где можно узнать больше про язык?
Нотации для платформенных типов
- T! означает " T или T? ",
- (Mutable)Collection! означает "коллекция Java типа T может быть (не)изменяемой, может быть nullable или нет",
- Array! означает "массив Java типа T (или подтипа T ), nullable или нет"
Геттеры и сеттеры
Методы, которые следуют конвенциям Java для геттеров и сеттеров (методы без аргументов с именами, начинающимися на get и методы с единственным аргументом, имена которых начинаются на set ) представлены как свойства в Kotlin. Методы доступа к полям Boolean (где имя геттера начинается с is , а имя сеттера начинается с set ) представлены как свойства, у которых имя совпадает с именем геттера.
Имейте в виду, что если класс Java имеет только сеттер, он не будет виден как свойство в Kotlin, потому что Kotlin не поддерживает set-only свойства на данный момент.
Какие преимущества есть у Kotlin по сравнению с Java?
Kotlin более лаконичен. Код на Kotlin примерно на 40% короче. Также Kotlin является типобезопасным. Благодаря null-безопасности приложения менее уязвимы к NullPointerException. В списке других возможностей: умное приведение типов, функции высшего порядка, функции-расширения и лямбда-выражения с получателями. Они позволяют писать выразительный код и поддерживать создание DSL.
Null-безопасность (Null-safety)
При вызове Kotlin функций из Java никто не мешает нам передавать null в качестве ненулевого параметра. Вот почему Kotlin генерирует проверки времени выполнения для всех публичных функций, которые ожидают непустые значения. Таким образом, мы немедленно получаем исключение NullPointerException в Java-коде.
Operators
Since Java has no way of marking methods for which it makes sense to use the operator syntax, Kotlin allows using any Java methods with the right name and signature as operator overloads and other conventions ( invoke() etc.) Calling Java methods using the infix call syntax is not allowed.
Inheritance from Java classes
At most one Java class (and as many Java interfaces as you like) can be a supertype for a class in Kotlin.
Свободен ли Kotlin?
Да. Kotlin был, есть и будет свободным. Он разрабатывается под лицензией Apache 2.0, а исходный код доступен на GitHub.
Поля экземпляра (Instance Fields)
Если вам нужно представить свойство Котлина в качестве поля в Java, вам нужно добавить к нему аннотацию @JvmField . Поле будет иметь такую же видимость, что и базовое свойство.Вы можете добавить свойству аннотацию @JvmField , если оно имеет backing field , не является приватным, не имеет open , override или const модификаторов и не является делегированным свойством.
Свойства с поздней инициализацией также отображаются как поля. Видимость поля будет такой же, как видимость сеттера свойства с поздней инициализацией.
Совместим ли Kotlin с Java?
Да, Kotlin на 100% совместим с Java. Возможности вашего существующего кода на Java правильно взаимодействовать с Kotlin уделено много внимания. Вы можете запросто вызывать код на Kotlin из Java и наоборот. Благодаря этому, внедрение Kotlin в проект намного проще и безопасней. Также стоит отметить автоматический конвертер кода из Java в Kotlin. Он встроен в IDE и позволяет упростить переход существующего кода на Kotlin.
Статические методы (Static Methods)
Как упоминалось выше, Kotlin представляет функции уровня пакета как статические методы. Kotlin также может генерировать статические методы для функций, определенных в именованных объектах или объектах-помощниках, если вы добавите аннотацию @JvmStatic к функции. Если вы используете эту аннотацию, компилятор создаст как статический метод во включающем классе объекта, так и метод экземпляра в самом объекте. Например:
Теперь foo() является статическим методом в Java, в то время как bar() нет:
То же самое для именованных объектов:
Аннотацию @JvmStatic можно также применить к свойству объекта или объекта-помощника, сделав его методы getter и setter статическими элементами в этом объекте или классе, содержащем объект-помощник.
Translation of type Nothing
The type Nothing is special, because it has no natural counterpart in Java. Indeed, every Java reference type, including java.lang.Void , accepts null as a value, and Nothing doesn't accept even that. So, this type cannot be accurately represented in the Java world. This is why Kotlin generates a raw type where an argument of type Nothing is used:
Compatibility modes for default methods
If there are clients that use your Kotlin interfaces compiled without the -Xjvm-default=all option, then they may be binary-incompatible with the code compiled with this option. To avoid breaking the compatibility with such clients, use the -Xjvm-default=all mode and mark interfaces with the @JvmDefaultWithCompatibility annotation. This allows you to add this annotation to all interfaces in the public API once, and you won't need to use any annotations for new non-public code.
Starting from Kotlin 1.6.20, you can compile modules in the default mode (the -Xjvm-default=disable compiler option) against modules compiled with the -Xjvm-default=all or -Xjvm-default=all-compatibility modes.
Learn more about compatibility modes:
disable
Default behavior. Do not generate JVM default methods and prohibit @JvmDefault annotation usage.
Generate JVM default methods for all interface declarations with bodies in the module. Do not generate DefaultImpls stubs for interface declarations with bodies, which are generated by default in the disable mode.
If interface inherits a method with body from an interface compiled in the disable mode and doesn't override it, then a DefaultImpls stub will be generated for it.
Breaks binary compatibility if some client code relies on the presence of DefaultImpls classes.
If interface delegation is used, all interface methods are delegated. The only exception are methods annotated with the deprecated @JvmDefault annotation.
all-compatibility
In addition to the all mode, generate compatibility stubs in the DefaultImpls classes. Compatibility stubs could be useful for library and runtime authors to keep backward binary compatibility for existing clients compiled against previous library versions. all and all-compatibility modes are changing the library ABI surface that clients will use after the recompilation of the library. In that sense, clients might be incompatible with previous library versions. This usually means that you need a proper library versioning, for example, major version increase in SemVer.
In case of inheritance from a Kotlin interface compiled in all or all-compatibility modes, DefaultImpls compatibility stubs will invoke the default method of the interface with standard JVM runtime resolution semantics.
Perform additional compatibility checks for classes inheriting generic interfaces where in some cases additional implicit method with specialized signatures was generated in the disable mode: unlike in the disable mode, the compiler will report an error if you don't override such method explicitly and don't annotate the class with @JvmDefaultWithoutCompatibility (see this YouTrack issue for more details).
Существуют ли книги про Kotlin?
Список книг есть здесь. Из самых популярных: Kotlin в Действии, написанная членами команды разработчиков Дмитрием Джемеровым и Светланой Исаковой, а также Kotlin for Android Developers.
Variant generics
When Kotlin classes make use of declaration-site variance, there are two options of how their usages are seen from the Java code. For example, imagine you have the following class and two functions that use it:
class Box
A naive way of translating these functions into Java would be this:
The problem is that in Kotlin you can write unboxBase(boxDerived(Derived())) but in Java that would be impossible because in Java the class Box is invariant in its parameter T , and thus Box is not a subtype of Box . To make this work in Java, you would have to define unboxBase as follows:
This declaration uses Java's wildcards types ( ? extends Base ) to emulate declaration-site variance through use-site variance, because it is all Java has.
To make Kotlin APIs work in Java, the compiler generates Box as Box for covariantly defined Box (or Foo for contravariantly defined Foo ) when it appears as a parameter. When it's a return value, wildcards are not generated, because otherwise Java clients will have to deal with them (and it's against the common Java coding style). Therefore, the functions from our example are actually translated as follows:
// return type - no wildcards Box boxDerived(Derived value) < . >// parameter - wildcards Base unboxBase(Box box)
When the argument type is final, there's usually no point in generating the wildcard, so Box is always Box , no matter what position it takes.
If you need wildcards where they are not generated by default, use the @JvmWildcard annotation:
fun boxDerived(value: Derived): Box = Box(value) // is translated to // Box boxDerived(Derived value)
In the opposite case, if you don't need wildcards where they are generated, use @JvmSuppressWildcards :
@JvmSuppressWildcards can be used not only on individual type arguments, but on entire declarations, such as functions or classes, causing all wildcards inside them to be suppressed.
Getters and setters
Methods that follow the Java conventions for getters and setters (no-argument methods with names starting with get and single-argument methods with names starting with set ) are represented as properties in Kotlin. Boolean accessor methods (where the name of the getter starts with is and the name of the setter starts with set ) are represented as properties which have the same name as the getter method.
Note that, if the Java class only has a setter, it isn't visible as a property in Kotlin because Kotlin doesn't support set-only properties.
Default methods in interfaces
Default methods are available only for targets JVM 1.8 and above.
Starting from JDK 1.8, interfaces in Java can contain default methods. To make all non-abstract members of Kotlin interfaces default for the Java classes implementing them, compile the Kotlin code with the -Xjvm-default=all compiler option.
Here is an example of a Kotlin interface with a default method:
// compile with -Xjvm-default=all interface Robot < fun move() < println("~walking~") >// will be default in the Java interface fun speak(): Unit >
The default implementation is available for Java classes implementing the interface.
C3PO c3po = new C3PO(); c3po.move(); // default implementation from the Robot interface c3po.speak();
Implementations of the interface can override default methods.
Prior to Kotlin 1.4, to generate default methods, you could use the @JvmDefault annotation on these methods. Compiling with -Xjvm-default=all in 1.4+ generally works as if you annotated all non-abstract methods of interfaces with @JvmDefault and compiled with -Xjvm-default=enable . However, there are cases when their behavior differs. Detailed information about the changes in default methods generation in Kotlin 1.4 is provided in this post on the Kotlin blog.
wait()/notify()
Effective Java Item 69 kindly suggests to prefer concurrency utilities to wait() and notify() . Thus, these methods are not available on references of type Any . If you really need to call them, you can cast to java.lang.Object :
Проходят ли какие-то мероприятия по Kotlin?
Да. Сейчас много пользовательских групп и митапов, которые сосредоточены на Kotlin. Список данных мероприятий можно найти на этом сайте. Также во всем мире проводятся специальные мероприятия - Kotlin Nights
Использование JNI в Kotlin
Чтобы объявить функцию, реализованную на нативном (C или C++) коде, Вам нужно пометить ее модификатором external :
Kotlin code can be easily called from Java. For example, instances of a Kotlin class can be seamlessly created and operated in Java methods. However, there are certain differences between Java and Kotlin that require attention when integrating Kotlin code into Java. On this page, we'll describe the ways to tailor the interop of your Kotlin code with its Java clients.
Кто разрабатывает Kotlin?
Kotlin разрабатывается в основном группой инженеров JetBrains (более чем 40 человек). Главный разработчик - Андрей Бреслав. В дополнение к команде, на GitHub есть примерно 100 активных вкладчиков.
Можно ли использовать Kotlin для веб-разработки?
Да. Кроме использования в бэкэнде, вы также можете использовать Kotlin/JS для клиентской стороны. Kotlin может использовать определения из DefinitelyTyped для статической типизации для популярных библиотек на JavaScript. Также Kotlin совместим с модульными системи, такими как AMD и CommonJS. Смотрите статью о разработке для клиентской стороны.
Object Methods
When Java types are imported into Kotlin, all the references of the type java.lang.Object are turned into Any . Since Any is not platform-specific, it only declares toString() , hashCode() and equals() as its members, so to make other members of java.lang.Object available, Kotlin uses extension functions.
Читайте также: