[java] Java에서 Kotlin 확장 기능에 액세스

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.ExtensionsPackageIDE가 올바르게 구성된 것 같습니다.

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 BytecodeDecompileMyModelExtensions.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 코드가 액세스하여 사용할 수 있습니다.