Java 코드에서 확장 기능에 액세스 할 수 있습니까?
Kotlin 파일에서 확장 기능을 정의했습니다.
package com.test.extensions
import com.test.model.MyModel
/**
*
*/
public fun MyModel.bar(): Int {
return this.name.length()
}
MyModel
(생성 된) Java 클래스는 어디에 있습니까 ? 이제 일반적인 Java 코드로 액세스하고 싶습니다.
MyModel model = new MyModel();
model.bar();
그러나 그것은 작동하지 않습니다. IDE가 bar()
메소드를 인식하지 못하고 컴파일이 실패합니다.
kotlin의 정적 함수와 함께 작동하는 것은 다음과 같습니다.
public fun bar(): Int {
return 2*2
}
사용하여 import com.test.extensions.ExtensionsPackage
IDE가 올바르게 구성된 것 같습니다.
kotlin 문서에서 전체 Java-interop 파일을 검색하고 많이 검색했지만 찾을 수 없었습니다.
내가 뭘 잘못하고 있죠? 이것이 가능합니까?
답변
파일에 선언 된 모든 Kotlin 함수는 기본적으로 동일한 패키지 내의 클래스에서 Kotlin 소스 파일에서 파생 된 이름을 사용하여 정적 메소드로 컴파일됩니다 (첫 글자는 대문자이고 “.kt” 확장자는 “Kt” 접미사 로 대체 됨 ) . 확장 기능을 위해 생성 된 메소드는 확장 기능 수신기 유형의 추가 첫 번째 매개 변수를 갖습니다.
원래 질문에 적용하면 Java 컴파일러는 이름이 example 인 Kotlin 소스 파일을 볼 수 있습니다.
package com.test.extensions
public fun MyModel.bar(): Int { /* actual code */ }
다음 Java 클래스가 선언 된 것처럼
package com.test.extensions
class ExampleKt {
public static int bar(MyModel receiver) { /* actual code */ }
}
Java 관점에서 확장 클래스에는 아무런 변화가 없으므로 도트 구문을 사용하여 이러한 메소드에 액세스 할 수는 없습니다. 그러나 여전히 일반적인 Java 정적 메소드로 호출 가능합니다.
import com.test.extensions.ExampleKt;
MyModel model = new MyModel();
ExampleKt.bar(model);
ExampleKt 클래스에는 정적 가져 오기를 사용할 수 있습니다.
import static com.test.extensions.ExampleKt.*;
MyModel model = new MyModel();
bar(model);
답변
Kotlin 최상위 확장 기능은 Java 정적 메소드로 컴파일됩니다.
Kotlin 파일 Extensions.kt
에 다음이 foo.bar
포함되어 있습니다.
fun String.bar(): Int {
...
}
동등한 Java 코드는 다음과 같습니다.
package foo.bar;
class ExtensionsKt {
public static int bar(String receiver) {
...
}
}
즉, Extensions.kt
라인을 포함 하지 않는 한
@file:JvmName("DemoUtils")
이 경우 Java 정적 클래스의 이름이 지정됩니다 DemoUtils
Kotlin에서는 확장 방법을 다른 방식으로 선언 할 수 있습니다. (예를 들어, 멤버 함수 또는 컴패니언 오브젝트의 확장으로서)
답변
다음 기능을 가진 NumberFormatting.kt라는 Kotlin 파일이 있습니다.
fun Double.formattedFuelAmountString(): String? {
val format = NumberFormat.getNumberInstance()
format.minimumFractionDigits = 2
format.maximumFractionDigits = 2
val string = format.format(this)
return string
}
자바에서는 필요한 가져 오기 후에 다음과 같은 방법으로 파일 NumberFormattingKt 를 통해 간단하게 액세스합니다.import ....extensions.NumberFormattingKt;
String literString = NumberFormattingKt.formattedFuelAmountString(item.getAmount());
답변
로 이동 한 다음을 클릭 하여 Kotlin 코드에서 생성 된 실제 Java 코드를 항상 확인할 수 있습니다 . 이것은 당신에게 엄청난 도움이 될 수 있습니다. 귀하의 경우 Java 코드는 다음과 같습니다.Tools > Kotlin > Show Kotlin Bytecode
Decompile
MyModelExtensions.kt
public final class MyModelExtensionsKt {
public static final int bar(@NotNull MyModel $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return $receiver.getName().length();
}
}
다음을 @JvmName
포함하는 파일 을 사용하여이를 개선 할 수 있습니다 bar
.
@file:JvmName("MyModels")
package io.sspinc.datahub.transformation
public fun MyModel.bar(): Int {
return this.name.length
}
이 코드는 다음과 같습니다.
public final class MyModels {
public static final int bar(@NotNull MyModel $receiver) {
Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
return $receiver.getName().length();
}
}
사용 MyModels
은 유틸리티 클래스에 효과적인 Java가 제안하는 것과 일치합니다. 다음과 같이 메소드 이름을 바꿀 수도 있습니다.
public fun MyModel.extractBar(): Int {
return this.name.length
}
그런 다음 Java 측면에서 관용적으로 보입니다.
MyModels.extractBar(model);
답변
클래스 파일에서 함수를 복제해야합니다.
예를 들어 Utils.kt 용 Kotlin 파일을 만듭니다.
코드를 입력하십시오
class Utils {
companion object {
@JvmStatic
fun String.getLength(): Int {//duplicate of func for java
return this.length
}
}
}
fun String.getLength(): Int {//kotlin extension function
return this.length
}
또는
class Utils {
companion object {
@JvmStatic
fun getLength(s: String): Int {//init func for java
return s.length
}
}
}
fun String.getLength(): Int {//kotlin extension function
return Utils.Companion.getLength(this)//calling java extension function in Companion
}
kotlin 사용시 :
val str = ""
val lenth = str.getLength()
Java에서는 다음을 사용하십시오.
String str = "";
Integer lenth = Utils.getLength(str);
답변
그것은 나를 위해 작동합니다 :
내 프로젝트는 Java로 만든 오래된 안드로이드 프로젝트입니다. 이제 첫 번째 kotlin 파일을 만들고 String 확장을 추가했습니다. fun String.isNotNullOrEmpty () : Boolean {…}
StringUtilsKt.isNotNullOrEmpty (thestring)을 사용하여 Java 파일에서 호출 할 수 있습니다.
내 kotlin 파일 이름은 StringUtils입니다
답변
다른 답변은 Kotlin 패키지 파일의 최상위에 위치한 확장 함수를 호출하는 경우를 다룹니다.
그러나 내 경우에는 클래스 내부에있는 확장 함수를 호출해야한다는 것입니다. 특히, 나는 Object를 다루고있었습니다.
해결책은 매우 간단 합니다.
확장 기능에으로 주석을 달기 @JvmStatic
만하면됩니다. Java 코드가 액세스하여 사용할 수 있습니다.