Classes in Kotlin can have type parameters, just like in Java: class Box[t: T] { var value = t } To create an instance of such a class, simply provide the type arguments: val box: Box = Box[1] But if the parameters can be inferred, for example, from the constructor arguments, you can omit the type arguments:
val box = Box[1] // 1 has type Int, so the compiler figures out that it is Box
Variance
One of the trickiest aspects of Java's type system is the wildcard types [see Java Generics FAQ]. Kotlin doesn't have these. Instead, Kotlin has declaration-site variance and type projections.
Let's think about why Java needs these mysterious wildcards. The problem is explained well in Effective Java, 3rd Edition, Item 31: Use bounded wildcards to increase API flexibility. First, generic types in Java are invariant, meaning that List is not a subtype of List. If List were not invariant, it would have been no better than Java's arrays, as the following code would have compiled but caused an exception at runtime:
// Java List strs = new ArrayList[]; List objs = strs; // !!! A compile-time error here saves us from a runtime exception later. objs.add[1]; // Put an Integer into a list of Strings String s = strs.get[0]; // !!! ClassCastException: Cannot cast Integer to String
Java prohibits such things in order to guarantee run-time safety. But this has implications. For example, consider the addAll[] method from the Collection interface. What's the signature of this method? Intuitively, you'd write it this way:
// Java interface Collection ... { void addAll[Collection items]; }
But then, you would not be able to do the following [which is perfectly safe]:
// Java void copyAll[Collection to, Collection from] { to.addAll[from]; // !!! Would not compile with the naive declaration of addAll: // Collection is not a subtype of Collection }
[In Java, you probably learned this the hard way, see Effective Java, 3rd Edition, Item 28: Prefer lists to arrays]
That's why the actual signature of addAll[] is the following:
// Java interface Collection ... { void addAll[Collection