Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to overload functions with same param types but one is nullable

Tags:

kotlin

I'm trying to add two extension function to Calendar Class in Android to convert the specific date-time pattern to Calendar and vise versa

fun Calendar.fromIsoString(date: String): Calendar = this.apply {
    time = SimpleDateFormat(SERVER_DATE_PATTERN, Locale.US).parse(date)
}

fun Calendar.fromIsoString(date: String?): Calendar? {
    if (date == null) return null
    time = SimpleDateFormat(SERVER_DATE_PATTERN, Locale.US).parse(date)
    return this
}

But it gives me the following Error:

Platform declaration clash: The following declarations have the same JVM signature (fromIsoString(Ljava/util/Calendar;Ljava/lang/String;)Ljava/util/Calendar;)

Is it possible to have these two functions besides each other? how?

Note: I somehow handled the problem by adding a Unit optional parameter to one of the functions:

fun Calendar.fromIsoString(date: String?, a: Unit = Unit): Calendar? {
if (date == null) return null
    time = SimpleDateFormat(SERVER_DATE_PATTERN, Locale.US).parse(date)
    return this
}

But I think it is tricky and not a good practice! Is there any better solution?

like image 372
Mosius Avatar asked May 23 '18 10:05

Mosius


People also ask

Can two overloaded functions differ only in the return type?

Function Overloading and Return Type in C++ Function overloading is possible in C++ and Java but only if the functions must differ from each other by the types and the number of arguments in the argument list. However, functions can not be overloaded if they differ only in the return type.

What are the restrictions on overloaded functions?

Restrictions on overloadingAny two functions in a set of overloaded functions must have different argument lists. Overloading functions that have argument lists of the same types, based on return type alone, is an error.

What will same for all the overloaded function?

An overloaded function is really just a set of different functions that happen to have the same name. The determination of which function to use for a particular call is resolved at compile time. In Java, function overloading is also known as compile-time polymorphism and static polymorphism.

Can we overload string method?

Yes, by method overloading. You can have any number of main methods in a class by method overloading. But JVM calls main() method which receives string array as arguments only.


1 Answers

There is a simple solution that allows you to do this without changing your methods or the name you want to call them from Kotlin.

For Kotlin the distinction between the two methods is clear, but for the JVM it is not. Therefore, just tell Kotlin that you want a different internal JVM name for one of the methods which will not impact Kotlin code at all. Only Java code would see the alternative name. For example:

fun Calendar.fromIsoString(date: String): Calendar = this.apply {
    // ... your code without change
}

@JvmName("fromIsoStringNullable") // <-- this solves your problem without changing the name in Kotlin
fun Calendar.fromIsoString(date: String?): Calendar? {
    // ... your code without change
}

voilà! no more error! You can call either version from Kotlin using the same name someCalendar.fromIsoString(...)

Other answers and comments suggesting the nullability is syntactical sugar are far from correct. These types are written into the bytecode as extra metadata that only Kotlin will see and enforce. But on top of that, it also adds a @Nullable annotation to the parameter. In fact, all Kotlin generated function parameters have @NotNull and @Nullable annotations in the bytecode for other languages or analyzers to see and enforce if they care enough to do so.

like image 199
Jayson Minard Avatar answered Oct 08 '22 21:10

Jayson Minard