0

On an Android project with both Kotlin and java, I want to use the Kotlin functions substringBeforeLast(delimiter) and substringAfterLast(delimiter) in some java files.

So i thought of using extensions. I did the following which works,

fun String.getStringAfterLast(): String{
    return this.substringAfterLast(".")
}

however i was thinking of passing the delimiter as a parameter, but it gives me an error when trying to use in java "remove 2nd argument..."

fun String.getStringBeforeLast(delimiter: String): String{
    return this.substringBeforeLast(delimiter)
}

Is the approach correct ? Can it be done ?

thahgr
  • 718
  • 1
  • 10
  • 27
  • does this post not contain what you're looking for ? https://stackoverflow.com/questions/28294509/accessing-kotlin-extension-functions-from-java – a_local_nobody Sep 27 '21 at 14:04
  • Assuming the file that you add this extension to is `Extension.kt`, then there is a generated class named `ExtensionKt` that can be used to directly access `getStringBeforeLast()` method from Java – Zain Sep 27 '21 at 14:07
  • @a_local_nobody no it does not contain the info about the second parameter – thahgr Sep 27 '21 at 14:10
  • Could you please share the Java code that breaks? – Joffrey Sep 27 '21 at 14:12
  • Are you sure you didn't accidentally create `getStringBeforeLast()` function only and then you try to invoke `getStringAfterLast()` from Java, which does not have a variant with the `delimiter` param yet? I ask because both your code samples are related to different functions which seems a little odd. – broot Sep 27 '21 at 14:21
  • 1
    Also remember that you can invoke functions of Kotlin stdlib directly from the Java, no problem. The only downside here is that this function receives additional, optional param, so using it directly is a little verbose: `StringsKt.substringBeforeLast(str, ".", str);`. – broot Sep 27 '21 at 14:29
  • I second what @broot said. Also, if these custom functions are just meant to be used from Java, it would make more sense to define them as regular functions instead of extensions, because it feels awkward for Java devs when they read the definition (and they will never be used this way anyway). Also, it's brittle to rely on the file name, and it adds the (maybe undesired) `-Kt` suffix, so wrapping them in an `object` would give you control over the name and the overall aspect of the Java call sites. – Joffrey Sep 27 '21 at 14:48
  • @broot i wasnt aware of the second parameter, that was my problem, why dont you post it as an answer, thanks – thahgr Sep 28 '21 at 06:37

1 Answers1

1

Your approach to this problem is correct and it should work. For example, with this Kotlin code:

fun String.getStringBeforeLast(delimiter: String): String{
    return this.substringBeforeLast(delimiter)
}

You should be able to invoke the function from Java like this:

ExtensionKt.getStringBeforeLast(str, ",");

If it didn't work then I guess there had to be some small mistake, like for example: you added delimiter param to getStringBeforeLast() function, but mistakenely tried to invoke getStringAfterLast() function from Java.

Also, you can always invoke functions of Kotlin stdlib directly from Java. Just note that substringBeforeLast()/substringAfterLast() actually receive one additional, optional parameter and you need to provide it from Java, making the code a little more verbose:

StringsKt.substringBeforeLast(str, ",", str);
broot
  • 21,588
  • 3
  • 30
  • 35