Java에서 Kotlin 확장 기능에 액세스
Java 코드에서 확장 기능에 액세스할 수 있는가?
나는 확장 기능을 코틀린 파일에 정의했다.
package com.test.extensions
import com.test.model.MyModel
/**
*
*/
public fun MyModel.bar(): Int {
return this.name.length()
}
어디에MyModel
(생성된) 자바 클래스 입니다.자바코드로 접속하고 싶었는데
MyModel model = new MyModel();
model.bar();
하지만, 그것은 효과가 없다.IDE는 방법을 인식하지 못하고 컴파일이 실패한다.
코틀린의 정적 함수와 함께 사용할 수 있는 기능:
public fun bar(): Int {
return 2*2
}
을 이용하여import com.test.extensions.ExtensionsPackage
그래서 내 IDE가 올바르게 구성된 것 같다.
코틀린 문서에서 자바 인터럽트 파일 전체를 뒤져보고 구글도 많이 검색했지만 찾을 수가 없었다.
내가 뭘 잘못하고 있는 거지?이게 가능할까?
파일에 선언된 모든 Kotlin 함수는 기본적으로 동일한 패키지 내의 클래스의 정적 메서드에 대해 컴파일되며, Kotlin 소스 파일에서 파생된 이름("Kt" 접미사로 대체된 첫 번째 문자 대문자 및 ".kt" 확장명)으로 컴파일된다.확장 기능을 위해 생성된 방법에는 확장 기능 수신기 유형이 포함된 추가 첫 번째 매개변수가 있을 것이다.
원래 질문에 적용하면 Java 컴파일러는 이름이 serem.kt인 Kotlin 소스 파일을 볼 수 있다.
package com.test.extensions
public fun MyModel.bar(): Int { /* actual code */ }
다음과 같은 자바 클래스가 선언된 것처럼.
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);
정적 가져오기를 예제Kt 클래스에 사용할 수 있음:
import static com.test.extensions.ExampleKt.*;
MyModel model = new MyModel();
bar(model);
코틀린 최상위 확장 함수는 자바 정적 방법으로 컴파일된다.
지정된 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
코틀린에서는 다른 방법으로 확장 방법을 선언할 수 있다. (예를 들어, 회원 함수로서 또는 동반 객체의 확장으로서)
나는 Number라는 코틀린 파일을 가지고 있다.다음 기능을 가진 포맷팅.kt
fun Double.formattedFuelAmountString(): String? {
val format = NumberFormat.getNumberInstance()
format.minimumFractionDigits = 2
format.maximumFractionDigits = 2
val string = format.format(this)
return string
}
Java에서 파일 번호로 간단히 액세스필요한 가져오기 후 다음 방법으로 포맷Ktimport ....extensions.NumberFormattingKt;
String literString = NumberFormattingKt.formattedFuelAmountString(item.getAmount());
새로운 KotlinEx로, 당신은 Java로 내선 전화를 직접 걸 수 있다.
ExtensionFileName.foo(field1...)
기본적으로, 그것이 하는 일은, 첫 번째 논쟁과 다른 주장들이 같은 장소에 있게 하는 것이다.
그래서 예를 들면.
확장명이 있음(Extension.kt 파일에)
Context.showToast(message:String){
...
}
자바에서는 이렇게 부른다.
ExtensionKt.showToast(context, message);
당신은 당신의 코틀린 코드에서 생성되는 실제 자바코드를 항상 볼 수 있다.Tools > Kotlin > Show Kotlin Bytecode
, 그런 다음 클릭Decompile
널 수 이것은 당신에게 엄청나게 도움이 될 수 있다.당신의 경우 Java 코드는 당신이 가지고 있다면 이렇게 보일 것이다.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
유효 자바(Effective Java)가 유틸리티 클래스에 대해 제안하는 내용과 일치한다.다음과 같이 메서드의 이름을 바꿀 수도 있다.
public fun MyModel.extractBar(): Int {
return this.name.length
}
자바 쪽에서 보면 관용적으로 보일 것이다.
MyModels.extractBar(model);
나한테는 효과가 있어:
코틀린
자바 코드
내 프로젝트는 Java로 만들어진 오래된 안드로이드 프로젝트야; 이제 나는 첫 번째 코틀린 파일을 만들고 String extensions fun String.isNotNullOrMempty(): Boolean {...}
다음 방법으로 자바 파일에서 호출할 수 있다.StringUtilsKt.isNotNullOrMempty(스트링)
내 kotlin 파일 이름은 StringUtils이다.
클래스 파일의 기능을 복제해야 하는 경우:
ex 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
}
OR
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
}
코틀린에서 다음을 사용하십시오.
val str = ""
val lenth = str.getLength()
Java에서는 다음을 사용하십시오.
String str = "";
Integer lenth = Utils.getLength(str);
여기서의 다른 답변은 코틀린 패키지 파일의 최상위 레벨에 있는 확장 기능을 호출하는 경우를 다룬다.
하지만, 나의 경우는 클래스 안에 있는 확장 기능을 불러야 한다는 것이었다.구체적으로, 나는 오브젝트를 다루고 있었다.
해결책은 믿을 수 없을 정도로 간단하다.
당신이 해야 할 일은 당신의 확장기능에 다음과 같이 주석을 달기만 하면 된다.@JvmStatic
, 네 할 수 거야당신의 자바코드는 그것에 접속하여 사용할 수 있을 것이다.
이와 같은 클래스를 연장하는 경우:
fun String.concatenatedLength(str: String): Int {
return (this.length + str.length)
}
fun f() {
var len = "one string".concatenatedLength("another string")
println(len)
}
이를 위해 다음과 같이 컴파일 형식:
import kotlin.jvm.internal.Intrinsics;
import org.jetbrains.annotations.NotNull;
public final class ExampleKt {
public static final int concatenatedLength(@NotNull String $receiver, @NotNull String str) {
Intrinsics.checkParameterIsNotNull((Object) $receiver, (String) "$receiver");
Intrinsics.checkParameterIsNotNull((Object) str, (String) "str");
return $receiver.length() + str.length();
}
public static final void f() {
int len = ExampleKt.concatenatedLength("one string", "another string");
System.out.println(len);
}
}
내가 알기로는 이건 불가능해.확장 문서를 읽어보니
public fun MyModel.bar(): Int {
return this.name.length()
}
서명으로 새로운 방법을 창조하다.
public static int MyModelBar(MyModel obj) {
return obj.name.length();
}
그리고 나서, 코틀린은 폼의 호출에 기능하는 지도를 만든다.myModel.bar()
, if.bar()
에서 찾을 수 없다MyModel
클래스는 자신이 출력하는 서명 및 이름 지정 체계와 일치하는 정적 방법을 찾는다.이는 확장이 정적으로 가져오기 때문에 정의된 방법을 재정의하지 않는다는 그들의 진술에서 나온 가정일 뿐이라는 점에 유의하십시오. 나는 그들이 확실히 알 만큼 충분히 멀리 가지 못했다.
따라서 위의 내용이 사실이라고 가정하면, 컴파일러는 단지 알 수 없는 방법이 물체에 호출되어 오류가 발생하는 것을 볼 수 있기 때문에, 코틀린 확장자는 단순한 오래된 자바 코드에서 호출될 수 있는 방법이 없다.
참조URL: https://stackoverflow.com/questions/28294509/accessing-kotlin-extension-functions-from-java
'Programing' 카테고리의 다른 글
로그아웃 시 vuex 비어 있는 상태 (0) | 2022.04.17 |
---|---|
Google 로그인 사용 오류 - vue "gapi가 정의되지 않음" (0) | 2022.04.17 |
C의 int 변수에 이중 정밀도를 할당하는 비직관적 결과 (0) | 2022.04.17 |
Vue.js - 요소 UI - 폼 유효성 검사 상태를 확인하는 방법 (0) | 2022.04.17 |
무료()가 내 어레이의 길이를 알고 있다면 왜 내 코드로 요청할 수 없는가? (0) | 2022.04.17 |