Directorio de artículos
1. Use la anotación @JvmField para exponer los campos de Kotlin a Java
1. Acceda a los campos de Kotlin a través de los métodos Getter y Setter en las clases de Java
No se puede acceder a los campos en Kotlin directamente en Java , y se debe llamar a los métodos Getter y Setter correspondientes para acceder;
Ejemplo de código:
Clase Kotlin: las propiedades de miembro declaradas en Kotlin son propiedades privadas privadas de forma predeterminada, y los métodos Getter y Setter se generan para ellas de forma predeterminada;
class Hello {
var name = "Tom"
}
Llamadas directas desde clases de Java: en las clases de Java, los campos de Kotlin no se pueden llamar directamente;
public class HelloJava {
public static void main(String[] args) {
Hello hello = new Hello();
System.out.println(hello.name);
}
}
Se informará un error en la clase Java:
'name' has private access in 'Hello'
En las clases de Java, los campos de Kotlin solo se pueden llamar a través de los métodos Getter y Setter ;
public class HelloJava {
public static void main(String[] args) {
Hello hello = new Hello();
System.out.println(hello.getName());
}
}
Resultados de la :
2. Acceso directo a campos Kotlin decorados con anotaciones @JvmField en clases Java
Si usa la anotación @JvmField para modificar las propiedades de los miembros en Kotlin , su función es exponer los campos de Kotlin a Java , y puede acceder directamente a los campos de Kotlin en Java sin ;
codigo kotlin:
class Hello {
@JvmField
var name = "Tom"
}
Código Java:
public class HelloJava {
public static void main(String[] args) {
Hello hello = new Hello();
System.out.println(hello.name);
}
}
Resultados de la :
La anotación @JvmField es equivalente a declarar un campo en Kotlin como un campo de Java , momento en el que Kotlin no generará automáticamente métodos Getter y Setter para el campo;
2. Use la anotación @JvmOverloads para modificar la función Kotlin
En Kotlin, los parámetros de función pueden tener sus propios valores predeterminados , y puede pasar directamente ;
Sin embargo, cuando Java llama a las funciones de Kotlin , el lenguaje Java no admite la sintaxis de los parámetros de función con valores predeterminados.Si se pasan los parámetros especificados, la función debe sobrecargarse;
El uso de la anotación @JvmOverloads para modificar la función Kotlin en Kotlin implementará automáticamente una serie de funciones sobrecargadas para los usuarios de Java;
por ejemplo, si la lista de parámetros es ( String , edad ), el uso de la anotación @JvmOverloads para modificar la función generará automáticamente
- 0 parámetros,
- 1 parámetro,
- 2 parámetros
La función ;
1. Ejemplo de llamada de función de parámetro predeterminado de Kotlin
Ejemplo de código de Kotlin: en la siguiente helloStudent
función , ambos parámetros se establecen con valores de parámetro predeterminados . Al llamar a esta función en Kotlin, puede pasar 0, 1 y 2 parámetros , y puede elegir qué parámetro pasar si pasa un parámetro;
class Hello {
fun helloStudent(name: String = "Tom", age: Int = 18) {
println("Student $name is $age years old , say hello !")
}
}
fun main() {
var hello = Hello();
hello.helloStudent()
hello.helloStudent("Jerry")
hello.helloStudent(age = 22)
hello.helloStudent("Bill", 12)
}
Resultados de la :
Student Tom is 18 years old , say hello !
Student Jerry is 18 years old , say hello !
Student Tom is 22 years old , say hello !
Student Bill is 12 years old , say hello !
Analice los datos de bytecode del código Kotlin anterior , vea los datos de bytecode en Kotlin Bytecode y descompílelos en código Java de la siguiente manera:
// Hello.java
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {
1, 1, 16},
bv = {
1, 0, 3},
k = 1,
d1 = {
"\u0000\u001e\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\b\n\u0000\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u001a\u0010\u0003\u001a\u00020\u00042\b\b\u0002\u0010\u0005\u001a\u00020\u00062\b\b\u0002\u0010\u0007\u001a\u00020\b¨\u0006\t"},
d2 = {
"LHello;", "", "()V", "helloStudent", "", "name", "", "age", "", "KotlinDemo"}
)
public final class Hello {
public final void helloStudent(@NotNull String name, int age) {
Intrinsics.checkParameterIsNotNull(name, "name");
String var3 = "Student " + name + " is " + age + " years old , say hello !";
boolean var4 = false;
System.out.println(var3);
}
// $FF: synthetic method
public static void helloStudent$default(Hello var0, String var1, int var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var1 = "Tom";
}
if ((var3 & 2) != 0) {
var2 = 18;
}
var0.helloStudent(var1, var2);
}
}
// HelloKt.java
import kotlin.Metadata;
@Metadata(
mv = {
1, 1, 16},
bv = {
1, 0, 3},
k = 2,
d1 = {
"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
d2 = {
"main", "", "KotlinDemo"}
)
public final class HelloKt {
public static final void main() {
Hello hello = new Hello();
Hello.helloStudent$default(hello, (String)null, 0, 3, (Object)null);
Hello.helloStudent$default(hello, "Jerry", 0, 2, (Object)null);
Hello.helloStudent$default(hello, (String)null, 22, 1, (Object)null);
hello.helloStudent("Bill", 12);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
2. Llame a la función de parámetro predeterminado de Kotlin en Java
Si desea pasar cualquier número y tipo de parámetros en código Java como Kotlin, debe usar la sobrecarga de funciones;
Si se llama directamente como en Kotlin, definitivamente se informará un error:
El uso de la anotación @JvmOverloads para modificar la función de Kotlin implementará automáticamente una serie de funciones sobrecargadas para los usuarios de Java;
Ejemplo de código Kotlin:
class Hello {
@JvmOverloads
fun helloStudent(name: String = "Tom", age: Int = 18) {
println("Student $name is $age years old , say hello !")
}
}
fun main() {
var hello = Hello();
hello.helloStudent()
hello.helloStudent("Jerry")
hello.helloStudent(age = 22)
hello.helloStudent("Bill", 12)
}
Ejemplo de código Java:
public class HelloJava {
public static void main(String[] args) {
Hello hello = new Hello();
hello.helloStudent();
hello.helloStudent("Jerry");
hello.helloStudent("Bill", 12);
}
}
Resultados de la :
Student Tom is 18 years old , say hello !
Student Jerry is 18 years old , say hello !
Student Bill is 12 years old , say hello !
Analice los datos de bytecode anteriores correspondientes a la clase de Kotlin anotados con @JvmOverloads y descompile el bytecode de nuevo al código Java, el contenido es el siguiente:
// Hello.java
import kotlin.Metadata;
import kotlin.jvm.JvmOverloads;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {
1, 1, 16},
bv = {
1, 0, 3},
k = 1,
d1 = {
"\u0000\u001e\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u0002\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\b\n\u0000\u0018\u00002\u00020\u0001B\u0005¢\u0006\u0002\u0010\u0002J\u001c\u0010\u0003\u001a\u00020\u00042\b\b\u0002\u0010\u0005\u001a\u00020\u00062\b\b\u0002\u0010\u0007\u001a\u00020\bH\u0007¨\u0006\t"},
d2 = {
"LHello;", "", "()V", "helloStudent", "", "name", "", "age", "", "KotlinDemo"}
)
public final class Hello {
@JvmOverloads
public final void helloStudent(@NotNull String name, int age) {
Intrinsics.checkParameterIsNotNull(name, "name");
String var3 = "Student " + name + " is " + age + " years old , say hello !";
boolean var4 = false;
System.out.println(var3);
}
// $FF: synthetic method
public static void helloStudent$default(Hello var0, String var1, int var2, int var3, Object var4) {
if ((var3 & 1) != 0) {
var1 = "Tom";
}
if ((var3 & 2) != 0) {
var2 = 18;
}
var0.helloStudent(var1, var2);
}
@JvmOverloads
public final void helloStudent(@NotNull String name) {
helloStudent$default(this, name, 0, 2, (Object)null);
}
@JvmOverloads
public final void helloStudent() {
helloStudent$default(this, (String)null, 0, 3, (Object)null);
}
}
// HelloKt.java
import kotlin.Metadata;
@Metadata(
mv = {
1, 1, 16},
bv = {
1, 0, 3},
k = 2,
d1 = {
"\u0000\b\n\u0000\n\u0002\u0010\u0002\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"},
d2 = {
"main", "", "KotlinDemo"}
)
public final class HelloKt {
public static final void main() {
Hello hello = new Hello();
Hello.helloStudent$default(hello, (String)null, 0, 3, (Object)null);
Hello.helloStudent$default(hello, "Jerry", 0, 2, (Object)null);
Hello.helloStudent$default(hello, (String)null, 22, 1, (Object)null);
hello.helloStudent("Bill", 12);
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
Después de usar la anotación @JvmOverloads , las funciones sobrecargadas con parámetros 0, 1 y 2 se generan automáticamente para la función helloStudent
en tiempo de compilación , de modo que estos métodos se pueden llamar directamente cuando se los llama en Java ;
@JvmOverloads
public final void helloStudent(@NotNull String name, int age) {
Intrinsics.checkParameterIsNotNull(name, "name");
String var3 = "Student " + name + " is " + age + " years old , say hello !";
boolean var4 = false;
System.out.println(var3);
}
@JvmOverloads
public final void helloStudent(@NotNull String name) {
helloStudent$default(this, name, 0, 2, (Object)null);
}
@JvmOverloads
public final void helloStudent() {
helloStudent$default(this, (String)null, 0, 3, (Object)null);
}
3. Use la anotación @JvmStatic para declarar miembros estáticos
En Kotlin, no existe el concepto de miembros estáticos.Cuando se necesita declarar un miembro estático , generalmente se declara en su objeto complementario Companion;
Al llamar a miembros en el objeto complementario Kotlin's Companion en Java , debe llamar de la siguiente forma:
Kotlin类.Companion.成员属性
Kotlin类.Companion.成员函数
Si desea llamar directamente a los miembros del objeto complementario Companion en Kotlin sin usar Companion ,
Puede estar en el objeto complementario ,
Use la anotación @JvmStatic para declarar miembros en el objeto complementario como miembros estáticos de Java,
En Java, se puede acceder a él como miembro estático;
1. Java normalmente accede a los miembros de objetos complementarios de Kotlin
En el siguiente código, para acceder a los miembros del objeto complementario de Kotlin en el lenguaje Java, primero debe obtener el objeto complementario de la clase Hello.Companion y luego acceder a los miembros del objeto complementario;
codigo kotlin:
class Hello {
companion object {
var name = "Tom"
fun say() {
println("Hello World")
}
}
}
Código Java:
public class HelloJava {
public static void main(String[] args) {
System.out.println(Hello.Companion.getName());
Hello.Companion.say();
}
}
Resultados de la :
Tom
Hello World
Vea el código Java descompilado del bytecode generado por esta clase de Kotlin:
import kotlin.Metadata;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {
1, 1, 16},
bv = {
1, 0, 3},
k = 1,
d1 = {
"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0004"},
d2 = {
"LHello;", "", "()V", "Companion", "KotlinDemo"}
)
public final class Hello {
@NotNull
private static String name = "Tom";
public static final Hello.Companion Companion = new Hello.Companion((DefaultConstructorMarker)null);
@Metadata(
mv = {
1, 1, 16},
bv = {
1, 0, 3},
k = 1,
d1 = {
"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0005\n\u0002\u0010\u0002\n\u0000\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\u0006\u0010\t\u001a\u00020\nR\u001a\u0010\u0003\u001a\u00020\u0004X\u0086\u000e¢\u0006\u000e\n\u0000\u001a\u0004\b\u0005\u0010\u0006\"\u0004\b\u0007\u0010\b¨\u0006\u000b"},
d2 = {
"LHello$Companion;", "", "()V", "name", "", "getName", "()Ljava/lang/String;", "setName", "(Ljava/lang/String;)V", "say", "", "KotlinDemo"}
)
public static final class Companion {
@NotNull
public final String getName() {
return Hello.name;
}
public final void setName(@NotNull String var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
Hello.name = var1;
}
public final void say() {
String var1 = "Hello World";
boolean var2 = false;
System.out.println(var1);
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
En los datos de código de bytes compilados por Kotlin, el atributo de miembro de nombre y la función de miembro de decir se definen en el objeto complementario Hello.Companion Si desea acceder a estos dos miembros, debe acceder a ellos a través de Hello.Companion;
2. Java accede estáticamente a los miembros de objetos complementarios de Kotlin
En el siguiente código, use la anotación @JvmStatic para modificar los miembros del objeto complementario en Kotlin, y luego se podrá acceder a estos miembros de forma estática en Java;
codigo kotlin:
class Hello {
companion object {
@JvmStatic
var name = "Tom"
@JvmStatic
fun say() {
println("Hello World")
}
}
}
Código Java:
public class HelloJava {
public static void main(String[] args) {
System.out.println(Hello.getName());
Hello.say();
}
}
Resultados de la :
Vea el código Java descompilado del bytecode generado por esta clase de Kotlin:
import kotlin.Metadata;
import kotlin.jvm.JvmStatic;
import kotlin.jvm.internal.DefaultConstructorMarker;
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
@Metadata(
mv = {
1, 1, 16},
bv = {
1, 0, 3},
k = 1,
d1 = {
"\u0000\f\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u0018\u0000 \u00032\u00020\u0001:\u0001\u0003B\u0005¢\u0006\u0002\u0010\u0002¨\u0006\u0004"},
d2 = {
"LHello;", "", "()V", "Companion", "KotlinDemo"}
)
public final class Hello {
@NotNull
private static String name = "Tom";
public static final Hello.Companion Companion = new Hello.Companion((DefaultConstructorMarker)null);
@NotNull
public static final String getName() {
Hello.Companion var10000 = Companion;
return name;
}
public static final void setName(@NotNull String var0) {
Hello.Companion var10000 = Companion;
name = var0;
}
@JvmStatic
public static final void say() {
Companion.say();
}
@Metadata(
mv = {
1, 1, 16},
bv = {
1, 0, 3},
k = 1,
d1 = {
"\u0000\u001a\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\b\u0002\n\u0002\u0010\u000e\n\u0002\b\u0006\n\u0002\u0010\u0002\n\u0000\b\u0086\u0003\u0018\u00002\u00020\u0001B\u0007\b\u0002¢\u0006\u0002\u0010\u0002J\b\u0010\n\u001a\u00020\u000bH\u0007R$\u0010\u0003\u001a\u00020\u00048\u0006@\u0006X\u0087\u000e¢\u0006\u0014\n\u0000\u0012\u0004\b\u0005\u0010\u0002\u001a\u0004\b\u0006\u0010\u0007\"\u0004\b\b\u0010\t¨\u0006\f"},
d2 = {
"LHello$Companion;", "", "()V", "name", "", "name$annotations", "getName", "()Ljava/lang/String;", "setName", "(Ljava/lang/String;)V", "say", "", "KotlinDemo"}
)
public static final class Companion {
/** @deprecated */
// $FF: synthetic method
@JvmStatic
public static void name$annotations() {
}
@NotNull
public final String getName() {
return Hello.name;
}
public final void setName(@NotNull String var1) {
Intrinsics.checkParameterIsNotNull(var1, "<set-?>");
Hello.name = var1;
}
@JvmStatic
public final void say() {
String var1 = "Hello World";
boolean var2 = false;
System.out.println(var1);
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
Cuando se compila la , se genera automáticamente
- Miembro estático Hello.name y sus métodos Getter y Setter estáticos,
- Hola, di método estático;
Estos dos miembros estáticos son miembros del objeto complementario Hello.Companion en la clase Kotlin, pero se generan en la clase Hello durante la compilación y se denominan miembros de la clase Hello;
public final class Hello {
@NotNull
private static String name = "Tom";
@NotNull
public static final String getName() {
Hello.Companion var10000 = Companion;
return name;
}
public static final void setName(@NotNull String var0) {
Hello.Companion var10000 = Companion;
name = var0;
}
@JvmStatic
public static final void say() {
Companion.say();
}
}