I have a java function:
public static void initialize(#NonNull Activity activity, Settings... settings) {}
I want to call it from kotlin:
fun initialize(activity: Activity, vararg settings: settings) = JavaClass.initialize(activity, settings)
But it does not compile, telling me that there is type mismatch, Settings is required, but the argument is kotlin.Array<out Settings>
I see that it's trying to match it with signture
public static void initialize(#NonNull Activity activity, Settings settings) {}
but I want to use
public static void initialize(#NonNull Activity activity, Settings[] settings) {}
You should use the following syntax:
fun initialize(activity: Activity, vararg settings: settings) =
JavaClass.initialize(activity, *settings)
https://kotlinlang.org/docs/reference/java-interop.html#java-varargs
Michael's answer is correct, though I'd like to make some additional comments.
The reason you cannot pass a Kotlin vararg parameter into a Java (or Kotlin) function that expects another vararg is because the compiler resolves the vararg into an Array.
Hence, it is as if you've declared your function as below (from the perspective of the function's internal scope):
fun initialize(activity: Activity, settings: Array<Settings>) = //...
This is why it is unintuitive that we need to use the spread * operator. As far as I can tell, there are two benefits to this design choice:
The spread operator, in addition to being used to populate variable arguments, can be used to mix-and-match between individual arguments and spreaded arrays. This means that Kotlin is giving us a convenient way to add additional parameters to a vararg list.
In Java, the following code does not compile:
Settings[] settings = //...
Setting myAdditionalSetting = new Setting();
JavaClass.initialize(activity, settings, myAdditionalSetting); //Compiler Error
However, in Kotlin we can do this:
JavaClass.initialize(activity, *settings, myAdditionalSetting)
The second benefit is increased safety. The spread operator compiles down to a call to Arrays.copyOf() which guarantees immutability of the spreaded values.i This ensures that the called function cannot corrupt the original array.
i: While the actual class references would be immutable, the objects they refer to might still be mutable.
Related
I'm coming to kotlin after working in mostly dynamically typed languages for years, so I get a lot of what I'm seeing, but I'm still tripping up a bit over reading some of the type annotations.
Most of them make sense (I've written some C++ and typescript so I'm not wholey familiar with more strictly type languages). so stuff like annotating the parameters and return types for functions, variable declaration, stuff like that makes sense.
What I'm having trouble with is the more complex annotations like looking at this explanation of the fold method when talking about higher order functions:
fun <T, R> Collection<T>.fold(
initial: R,
combine: (acc: R, nextElement: T) -> R
): R {
var accumulator: R = initial
for (element: T in this) {
accumulator = combine(accumulator, element)
}
return accumulator
}
I get that:
the Collection refers to an arbitrary collection with elements that are of type T
the fold method call takes an value of type R named initial as the first argument and a callable function labeled combine as the second argument
the callable function will be called for each element of the collection with an accumulator of type R labeled acc and the next element of the collection of type T (since it's a collection of Ts) labeled nextElement
The callable function will return a type R in the end
The fold method will return a type R in the end
And I can use it like this:
val greetings = listOf("hey", "hi", "yo", "what's up")
val personalized = greetings.fold("", { carry, current -> "${carry}\n$current, Chris." })
println(personalized)
That all makes sense, but what does the <T, R> between the fun and the Collection mean? What is that part called? (It's hard to search for an explanation when you don't know what the thing you're looking for is called :P)
And more importantly, is there a section of the documentation that specifically talks about how to read these annotations or what each are called? I've been looking through the docs and searching in general for an explanation of how to read the type annotations and I can't find anything.
It feels like a silly question, but to the uninitiated it's kind of daunting and the docs are written as if you already understand that part of the language.
As Alexey already said, these names between angled brackets after the fun keyword are called "type parameters". They are used to declare generic functions.
the Collection refers to an arbitrary collection with elements that are of type T
Here you can see that Collection and T play different roles: Collection is a well-known defined type that you are referencing, while T is just a name that you arbitrarily choose for the definition of this function.
We want the compiler to check that Collection is a type that is defined and imported, and if you make a typo there will be a compile error.
On the other hand, we don't want that for T and R, so it is necessary to mention them in a special syntactic place so that the compiler knows you're just making up arbitrary names for the sake of the function definition.
It is nice to draw a parallel between the type parameters and the method arguments. The method arguments are also arbitrary names that you define in the signature and use in the function body, as opposed to class members like properties, which you can access without declaring them as arguments.
Just like the values of the arguments are passed when you call a method, and can be different for each different invocation, the "values" of the type parameters are also given at the call site, and can be different for each invocation (they are often inferred, though, so you don't see them).
Note that the "value" of a type parameter is a type (e.g. String), not a value in the usual sense like the string "abc". You can actually specify these types explicitly on the call site if you want:
listOf(1, 2, 3).fold<Int, Int>(42) { acc, e -> acc + e }
The syntax on the call site is similar to the declaration site, it uses <>, except that it's written after the function name.
In general, these types are easily inferred by the compiler using the argument types or the return type in the context of the call site, that's why it's often unnecessary to explicitly specify them.
Difference with generics at the class level
It may seem weird that the methods in the interface List don't need to declare such type parameters, despite the fact that they use generic types:
interface MutableList<T> {
fun add(element: T): Boolean {
//....
}
}
This is because T is already "well-defined" when using it for the method declaration: it was already defined as a type parameter for the List interface itself. The mechanism is the same, but the difference is the scope of the definition: class-level type parameters are defined by the instance of the class (you can create a List<Int> or a List<String>, and this is chosen when you create your instance), while function type parameters are defined by each call to the function.
You can even combine both:
interface List<T> {
fun <R> map(transform: (T) -> R): List<R> {
//...
}
}
Here T will be determined by the list instance on which you call map, but R can be different for each call to map even on the same list instance.
<T, R> are the type parameters. Since you are familiar with C++, it's like
template <typename T, typename R>
It just happens to be placed after the fun keyword in Kotlin (and after the type name when declaring a generic class/interface/type alias) instead of before the function definition.
In Java, we can create an utilities class like this:
final class Utils {
public static boolean foo() {
return false;
}
}
But how to do this in Kotlin?
I try using functions inside object:
object Utils {
fun foo(): Boolean {
return false
}
}
But when call this method from Java code it need to add INSTANCE. Ex: Utils.INSTANCE.foo().
Then I change to declare it as top-level function (without class or object):
#file:JvmName("Utils")
#file:JvmMultifileClass
fun foo(): Boolean {
return true
}
Then I can call Utils.foo() from Java code. But from Kotlin code I got Unresolved reference compiler error. It only allow be to use foo() function directly (without Utils prefix).
So what is the best approach for declaring utils class in Kotlin?
The last solution you've proposed is actually quite idiomatic in Kotlin - there's no need to scope your function inside anything, top level functions are just fine to use for utilities, in fact, that's what most of the standard library consists of.
You've used the #JvmName annotation the right way too, that's exactly how you're supposed to make these top level functions easily callable for Java users.
Note that you only need #JvmMultifileClass if you are putting your top level functions in different files but still want them to end up grouped in the same class file (again, only for Java users). If you only have one file, or you're giving different names per file, you don't need this annotation.
If for some reason you want the same Utils.foo() syntax in both Java and Kotlin, the solution with an object and then #JvmStatic per method is the way to do that, as already shown by #marianosimone in this answer.
You'd need to use #JvmStatic for that:
In Kotlin:
object Utils {
#JvmStatic
fun foo(): Boolean = true
}
val test = Utils.foo()
In Java:
final boolean test = Utils.foo()
Note that the util class you used in Java was the only way to supply additional functions there, for anything that did not belong to a particular type or object. Using object for that in Kotlin does not make any sense. It isn't a singleton, right?
The second approach you mentioned is rather the way to go for utility functions. Internally such functions get translated to static ones and as you can see they become the static util classes in Java you are searching for, as you can't have standalone functions in Java without a class or enum. In Kotlin itself however they are just functions.
Some even count utility classes to the anti-patterns. Functions on the other hand make totally sense without a class or object whose name hasn't so much meaning anyway.
I have a generically typed class Builder<T> that takes a constructor argument Class<T> so I can keep the type around. This is a class that I use a lot in java code so I don't want to change the signature.
When I try to use the constructor like this:
Builder<List<Number>>(List<Number>::class)
I get an error: "Only classes are allowed on the left hand side of a class literal"
Any way to resolve this?
I can't change the constructor for Builder, too many java classes rely upon it.
I understand the whole type erasure issue, I really just want to make the compiler happy.
Due to generic type erasure List class has a single implementation for all its generic instantiations. You can only get a class corresponding to List<*> type, and thus create only Builder<List<*>>.
That builder instance is suitable for building a list of something. And again due to type erasure what that something is you can decide by yourself with the help of unchecked casts:
Builder(List::class.java) as Builder<List<Number>>
Builder(List::class.java as Class<List<Number>>)
Another approach is to create inline reified helper function:
inline fun <reified T : Any> Builder() = Builder(T::class.java)
and use it the following way:
Builder<List<Number>>()
The solution is to use reified generics in couple with super class tokens.
Please refer to this question for the method explained. Constructors in Kotlin don't support reified generics, but you can use TypeReference described there to write a builder factory function which will retain actual generic parameters at runtime:
inline <reified T: Any> fun builder(): Builder<T> {
val type = object : TypeReference<T>() {}.type
return Builder(type)
}
Then inside Builder you can check if type is ParameterizedType, and if it is, type.actualTypeArguments will contain the actual generic parameters.
For example, builder<List<Number>>() will retain the information about Number at runtime.
The limitation of this approach is that you cannot use non-reified generic as a reified type parameter because the type must be known at compile-time.
In Kotlin, a function with at least one argument can be defined either as a regular non-member function or as an extension function with one argument being a receiver.
As to the scoping, there seems to be no difference: both can be declared inside or outside classes and other functions, and both can or cannot have visibility modifiers equally.
Language reference seems not to recommend using regular functions or extension functions for different situations.
So, my question is: when do extension functions give advantage over regular non-member ones? And when regular ones over extensions?
foo.bar(baz, baq) vs bar(foo, baz, baq).
Is it just a hint of a function semantics (receiver is definitely in focus) or are there cases when using extensions functions makes code much cleaner or opens up opportunities?
Extension functions are useful in a few cases, and mandatory in others:
Idiomatic Cases:
When you want to enhance, extend or change an existing API. An extension function is the idiomatic way to change a class by adding new functionality. You can add extension functions and extension properties. See an example in the Jackson-Kotlin Module for adding methods to the ObjectMapper class simplifying the handling of TypeReference and generics.
Adding null safety to new or existing methods that cannot be called on a null. For example the extension function for String of String?.isNullOrBlank() allows you to use that function even on a null String without having to do your own null check first. The function itself does the check before calling internal functions. See documentation for extensions with Nullable Receiver
Mandatory Cases:
When you want an inline default function for an interface, you must use an extension function to add it to the interface because you cannot do so within the interface declaration (inlined functions must be final which is not currently allowed within an interface). This is useful when you need inline reified functions, for example this code from Injekt
When you want to add for (item in collection) { ... } support to a class that does not currently support that usage. You can add an iterator() extension method that follows the rules described in the for loops documentation -- even the returned iterator-like object can use extensions to satisfy the rules of providing next() and hasNext().
Adding operators to existing classes such as + and * (specialization of #1 but you can't do this in any other way, so is mandatory). See documentation for operator overloading
Optional Cases:
You want to control the scoping of when something is visible to a caller, so you extend the class only in the context in which you will allow the call to be visible. This is optional because you could just allow the extensions to be seen always. see answer in other SO question for scoping extension functions
You have an interface that you want to simplify the required implementation, while still allowing more easy helper functions for the user. You can optionally add default methods for the interface to help, or use extension functions to add the non-expected-to-be-implemented parts of the interface. One allows overriding of the defaults, the other does not (except for precedence of extensions vs. members).
When you want to relate functions to a category of functionality; extension functions use their receiver class as a place from which to find them. Their name space becomes the class (or classes) from which they can be triggered. Whereas top-level functions will be harder to find, and will fill up the global name space in IDE code completion dialogs. You can also fix existing library name space issues. For example, in Java 7 you have the Path class and it is difficult to find the Files.exist(path) method because it is name spaced oddly. The function could be placed directly on Path.exists() instead. (#kirill)
Precedence Rules:
When extending existing classes, keep the precedence rules in mind. They are described in KT-10806 as:
For each implicit receiver on current context we try members, then local extension functions(also parameters which have extension function type), then non-local extensions.
Extension functions play really well with the safe call operator ?.. If you expect that the argument of the function will sometimes be null, instead of early returning, make it the receiver of an extension function.
Ordinary function:
fun nullableSubstring(s: String?, from: Int, to: Int): String? {
if (s == null) {
return null
}
return s.substring(from, to)
}
Extension function:
fun String.extensionSubstring(from: Int, to: Int) = substring(from, to)
Call site:
fun main(args: Array<String>) {
val s: String? = null
val maybeSubstring = nullableSubstring(s, 0, 1)
val alsoMaybeSubstring = s?.extensionSubstring(0, 1)
As you can see, both do the same thing, however the extension function is shorter and on the call site, it's immediately clear that the result will be nullable.
There is at least one case where extension functions are a must - call chaining, also known as "fluent style":
foo.doX().doY().doZ()
Suppose you want to extend the Stream interface from Java 8 with you own operations. Of course, you can use ordinary functions for that, but it will look ugly as hell:
doZ(doY(doX(someStream())))
Clearly, you want to use extension functions for that.
Also, you cannot make ordinary functions infix, but you can do it with extension functions:
infix fun <A, B, C> ((A) -> B).`|`(f: (B) -> C): (A) -> C = { a -> f(this(a)) }
#Test
fun pipe() {
val mul2 = { x: Int -> x * 2 }
val add1 = { x: Int -> x + 1 }
assertEquals("7", (mul2 `|` add1 `|` Any::toString)(3))
}
There are cases where you have to use extension methods. E.g. if you have some list implementation MyList<T>, you can write an extension method like
fun Int MyList<Int>.sum() { ... }
It is impossible to write this as a "normal" method.
I am learning Kotlin and it is looking likely I may want to use it as my primary language within the next year. However, I keep getting conflicting research that Kotlin does or does not have immutable collections and I'm trying to figure out if I need to use Google Guava.
Can someone please give me some guidance on this? Does it by default use Immutable collections? What operators return mutable or immutable collections? If not, are there plans to implement them?
Kotlin's List from the standard library is readonly:
interface List<out E> : Collection<E> (source)
A generic ordered collection of elements. Methods in this interface
support only read-only access to the list; read/write access is
supported through the MutableList interface.
Parameters
E - the type of elements contained in the list.
As mentioned, there is also the MutableList
interface MutableList<E> : List<E>, MutableCollection<E> (source)
A generic ordered collection of elements that supports adding and
removing elements.
Parameters
E - the type of elements contained in the list.
Due to this, Kotlin enforces readonly behaviour through its interfaces, instead of throwing Exceptions on runtime like default Java implementations do.
Likewise, there is a MutableCollection, MutableIterable, MutableIterator, MutableListIterator, MutableMap, and MutableSet, see the stdlib documentation.
It is confusing but there are three, not two types of immutability:
Mutable - you are supposed to change the collection (Kotlin's MutableList)
Readonly - you are NOT supposed to change it (Kotlin's List) but something may (cast to Mutable, or change from Java)
Immutable - no one can change it (Guavas's immutable collections)
So in case (2) List is just an interface that does not have mutating methods, but you can change the instance if you cast it to MutableList.
With Guava (case (3)) you are safe from anybody to change the collection, even with a cast or from another thread.
Kotlin chose to be readonly in order to use Java collections directly, so there is no overhead or conversion in using Java collections..
As you see in other answers, Kotlin has readonly interfaces to mutable collections that let you view a collection through a readonly lens. But the collection can be bypassed via casting or manipulated from Java. But in cooperative Kotlin code that is fine, most uses do not need truly immutable collections and if your team avoids casts to the mutable form of the collection then maybe you don't need fully immutable collections.
The Kotlin collections allow both copy-on-change mutations, as well as lazy mutations. So to answer part of your questions, things like filter, map, flatmap, operators + - all create copies when used against non lazy collections. When used on a Sequence they modify the values as the collection as it is accessed and continue to be lazy (resulting in another Sequence). Although for a Sequence, calling anything such as toList, toSet, toMap will result in the final copy being made. By naming convention almost anything that starts with to is making a copy.
In other words, most operators return you the same type as you started with, and if that type is "readonly" then you will receive a copy. If that type is lazy, then you will lazily apply the change until you demand the collection in its entirety.
Some people want them for other reasons, such as parallel processing. In those cases, it might be best to look at really high performance collections designed just for those purposes. And only use them in those cases, not in all general cases.
In the JVM world it is hard to avoid interop with libraries that want standard Java collections, and converting to/from these collections adds a lot of pain and overhead for libraries that do not support the common interfaces. Kotlin gives a good mix of interop and lack of conversion, with readonly protection by contract.
So if you can't avoid wanting immutable collections, Kotlin easily works with anything from the JVM space:
Guava (https://github.com/google/guava)
Dexx a port of the Scala collections to Java (https://github.com/andrewoma/dexx) with Kotlin helpers (https://github.com/andrewoma/dexx/blob/master/kollection/README.md)
Eclipse Collections (formerly GS-Collections) a really high performance, JDK compatible, top performer in parallel processing with immutable and mutable variations (home: https://www.eclipse.org/collections/ and Github: https://github.com/eclipse/eclipse-collections)
PCollections (http://pcollections.org/)
Also, the Kotlin team is working on Immutable Collections natively for Kotlin, that effort can be seen here:
https://github.com/Kotlin/kotlinx.collections.immutable
There are many other collection frameworks out there for all different needs and constraints, Google is your friend for finding them. There is no reason the Kotlin team needs to reinvent them for its standard library. You have a lot of options, and they specialize in different things such as performance, memory use, not-boxing, immutability, etc. "Choice is Good" ... therefore some others: HPCC, HPCC-RT, FastUtil, Koloboke, Trove and more...
There are even efforts like Pure4J which since Kotlin supports Annotation processing now, maybe can have a port to Kotlin for similar ideals.
Kotlin 1.0 will not have immutable collections in the standard library. It does, however, have read-only and mutable interfaces. And nothing prevents you from using third party immutable collection libraries.
Methods in Kotlin's List interface "support only read-only access to the list" while methods in its MutableList interface support "adding and removing elements". Both of these, however, are only interfaces.
Kotlin's List interface enforces read-only access at compile-time instead of deferring such checks to run-time like java.util.Collections.unmodifiableList(java.util.List) (which "returns an unmodifiable view of the specified list... [where] attempts to modify the returned list... result in an UnsupportedOperationException." It does not enforce immutability.
Consider the following Kotlin code:
import com.google.common.collect.ImmutableList
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
fun main(args: Array<String>) {
val readOnlyList: List<Int> = arrayListOf(1, 2, 3)
val mutableList: MutableList<Int> = readOnlyList as MutableList<Int>
val immutableList: ImmutableList<Int> = ImmutableList.copyOf(readOnlyList)
assertEquals(readOnlyList, mutableList)
assertEquals(mutableList, immutableList)
// readOnlyList.add(4) // Kotlin: Unresolved reference: add
mutableList.add(4)
assertFailsWith(UnsupportedOperationException::class) { immutableList.add(4) }
assertEquals(readOnlyList, mutableList)
assertEquals(mutableList, immutableList)
}
Notice how readOnlyList is a List and methods such as add cannot be resolved (and won't compile), mutableList can naturally be mutated, and add on immutableList (from Google Guava) can also be resolved at compile-time but throws an exception at run-time.
All of the above assertions pass with exception of the last one which results in Exception in thread "main" java.lang.AssertionError: Expected <[1, 2, 3, 4]>, actual <[1, 2, 3]>. i.e. We successfully mutated a read-only List!
Note that using listOf(...) instead of arrayListOf(...) returns an effectively immutable list as you cannot cast it to any mutable list type. However, using the List interface for a variable does not prevent a MutableList from being assigned to it (MutableList<E> extends List<E>).
Finally, note that an interface in Kotlin (as well as in Java) cannot enforce immutability as it "cannot store state" (see Interfaces). As such, if you want an immutable collection you need to use something like those provided by Google Guava.
See also ImmutableCollectionsExplained · google/guava Wiki · GitHub
NOTE: This answer is here because the code is simple and open-source and you can use this idea to make your collections that you create immutable. It is not intended only as an advertisement of the library.
In Klutter library, are new Kotlin Immutable wrappers that use Kotlin delegation to wrap a existing Kotlin collection interface with a protective layer without any performance hit. There is then no way to cast the collection, its iterator, or other collections it might return into something that could be modified. They become in effect Immutable.
Klutter 1.20.0 released which adds immutable protectors for existing collections, based on a SO answer by #miensol provides a light-weight delegate around collections that prevents any avenue of modification including casting to a mutable type then modifying. And Klutter goes a step further by protecting sub collections such as iterator, listIterator, entrySet, etc. All of those doors are closed and using Kotlin delegation for most methods you take no hit in performance. Simply call myCollection.asReadonly() (protect) or myCollection.toImmutable() (copy then protect) and the result is the same interface but protected.
Here is an example from the code showing how simply the technique is, by basically delegating the interface to the actual class while overriding mutation methods and any sub-collections returned are wrapped on the fly.
/**
* Wraps a List with a lightweight delegating class that prevents casting back to mutable type
*/
open class ReadOnlyList <T>(protected val delegate: List<T>) : List<T> by delegate, ReadOnly, Serializable {
companion object {
#JvmField val serialVersionUID = 1L
}
override fun iterator(): Iterator<T> {
return delegate.iterator().asReadOnly()
}
override fun listIterator(): ListIterator<T> {
return delegate.listIterator().asReadOnly()
}
override fun listIterator(index: Int): ListIterator<T> {
return delegate.listIterator(index).asReadOnly()
}
override fun subList(fromIndex: Int, toIndex: Int): List<T> {
return delegate.subList(fromIndex, toIndex).asReadOnly()
}
override fun toString(): String {
return "ReadOnly: ${super.toString()}"
}
override fun equals(other: Any?): Boolean {
return delegate.equals(other)
}
override fun hashCode(): Int {
return delegate.hashCode()
}
}
Along with helper extension functions to make it easy to access:
/**
* Wraps the List with a lightweight delegating class that prevents casting back to mutable type,
* specializing for the case of the RandomAccess marker interface being retained if it was there originally
*/
fun <T> List<T>.asReadOnly(): List<T> {
return this.whenNotAlreadyReadOnly {
when (it) {
is RandomAccess -> ReadOnlyRandomAccessList(it)
else -> ReadOnlyList(it)
}
}
}
/**
* Copies the List and then wraps with a lightweight delegating class that prevents casting back to mutable type,
* specializing for the case of the RandomAccess marker interface being retained if it was there originally
*/
#Suppress("UNCHECKED_CAST")
fun <T> List<T>.toImmutable(): List<T> {
val copy = when (this) {
is RandomAccess -> ArrayList<T>(this)
else -> this.toList()
}
return when (copy) {
is RandomAccess -> ReadOnlyRandomAccessList(copy)
else -> ReadOnlyList(copy)
}
}
You can see the idea and extrapolate to create the missing classes from this code which repeats the patterns for other referenced types. Or view the full code here:
https://github.com/kohesive/klutter/blob/master/core-jdk6/src/main/kotlin/uy/klutter/core/common/Immutable.kt
And with tests showing some of the tricks that allowed modifications before, but now do not, along with the blocked casts and calls using these wrappers.
https://github.com/kohesive/klutter/blob/master/core-jdk6/src/test/kotlin/uy/klutter/core/collections/TestImmutable.kt
Now we have https://github.com/Kotlin/kotlinx.collections.immutable.
fun Iterable<T>.toImmutableList(): ImmutableList<T>
fun Iterable<T>.toImmutableSet(): ImmutableSet<T>
fun Iterable<T>.toPersistentList(): PersistentList<T>
fun Iterable<T>.toPersistentSet(): PersistentSet<T>