The documentation for Kotlin is now located on the new site. This page is kept for historical reasons

Skip to end of metadata
Go to start of metadata

The documentation for Kotlin is now located on the new site. This page is kept for historical reasons

In Kotlin, everything is an object in the sense that one can call member functions and properties on any variable. Some types are built-in, because their implementation is optimized, but for the used they look like ordinary classes. In this section we describe most of these types: numbers, characters, booleans and arrays.


Kotlin handles numbers in a way close to Java, but not exactly the same. For example, there are no implicit widening conversions or numbers, and literals are slightly different in some cases.

Kotlin provides the following built-in types representing numbers (this is close to Java):















Note that characters are not numbers in Kotlin.


On the Java platform, numbers are physically stored as JVM primitive types, unless we need a nullable number reference (e.g. Int?) or generics are involved. In the latter cases numbers are boxed.

Note that boxing of numbers does not preserve identity:

val a : Int = 10000 
print(a identityEquals a) // Prints 'true' 
val boxedA : Int? = a 
val anotherBoxedA : Int? = a 
print(boxedA identityEquals anotherBoxedA) // !!!Prints 'false'!!!

On the other hand, it preserves equality:

val a : Int = 10000 
print(a == a) // Prints 'true' 
val boxedA : Int? = a 
val anotherBoxedA : Int? = a 
print(boxedA == anotherBoxedA) // Prints 'true'

Explicit conversions

Due to different representations, smaller types are not subtypes of bigger ones.
If they were, we would have troubles of the following sort:

// Hypothetical code, does not actually compile: 
val a : Int? = 1 // A boxed Int (java.lang.Integer) 
val b : Long? = a // implicit conversion yields a boxed Long (java.lang.Long) 
print(a == b) // Surprise! This prints "false" as Long's equals() check for other part to be Long as well

So not only identity, but even equality would have been lost silently all over the place.

As a consequence, smaller types are NOT implicitly converted to bigger types. This means that one cannot assign a value of type Byte to an Integer variable without an explicit conversion:

val b : Byte = 1 // OK, literals are checked statically 
val i : Int = 

One can use explicit conversions to widen numbers:

val i : Int = b.toInt() // OK: explicitly widened

Every number type supports the following conversions:

  • toByte() : Byte
  • toShort() : Short
  • toInt() : Int
  • toLong() : Long
  • toFloat() : Float
  • toDouble() : Double
  • toChar() : Char

Absence of implicit conversions is rarely noticeable because one can use literals almost freely cause the type is inferred from the context, and arithmetical operations are overloaded for appropriate conversions, for example

val l = 1.toLong() + 3 // Long + Int => Long


All the integer literals are written in the same way:

  • Decimals: 123, 123L, 123.5, 123.5e10, 123.5f
  • Hexadecimals: 0x0F
  • Binaries: 0b00001011

NOTE: Octal literals are not supported.

You can only use a capital "L" for suffixing Long values (little "l" looks too much like "1" in many fonts), both "F" and "f" are allowed for Float's. Alternatively, one could use explicit conversions to specify a type for a literal:

val list = list(1.toLong(), 100000000000, 2.toLong())


Kotlin supports the standard set of arithmetical operations over numbers, which are declared as members of appropriate classes (but the compiler optimizes the calls down to the corresponding instructions). See Operator overloading.

As of bitwise operations, there're no special characters for them, but just named functions that can be called in infix form, for example:

val x = (1 shl 2) and 0x000FF000

Here is the complete list of bitwise operations (available for Int and Long only):

  • shl(bits) – signed shift left (Java's <<)
  • shr(bits) – signed shift right (Java's >>)
  • ushr(bits) – unsigned shift right (Java's >>>)
  • and(bits) – bitwise and
  • or(bits) – bitwise or
  • xor(bits) – bitwise xor
  • inv() – bitwise inversion


Characters are represented by the type Char. They are can not be treated directly as numbers:

fun check(c : Char) { 
  if (c 
 1) { // ERROR: incompatible types 
    // ... 

Character literals go in single quotes: '1', '\n', '\uFF00'.
One can explicitly convert a character to an Int number:

fun decimalDigitValue(c : Char) : Int { 
  if (c !in '0'..'9') 
    throw IllegalArgumentException("Out of range") 
  return c.toInt() - '0'.toInt() // Explicit conversions to numbers 

Like numbers, characters are boxed when a nullable reference is needed. Identity is not preserved by the boxing operation.


The type Boolean represents booleans, and has two values: true and false.

Booleans are boxed if a nullable reference is needed.

Built-in operations on booleans include

  • || – lazy disjunction
  • && – lazy conjunction


Arrays in Kotlin are represented by the Array class, that has get and set functions (that turn into [] by operator overloading conventions), and size, along with a few other useful member functions:

class Array<T>(val size : Int, init : (Int) -> T) { 
  fun get(index : Int) : T 
  fun set(index : Int, value : T) : Unit 
  fun iterator() : Iterator<T> 
  val indices : IntRange 

To create an array one can call its constructor providing the array size and a function that knows how to initialize elements of the array:

val asc = Array<Int>(5, {i -> i * i}) // Creates an array [0, 1, 4, 9, 16]

Or, alternatively, one can use a library function array() and pass the item values to it, so that array(1, 2, 3) creates an array [1, 2, 3].

As we said above, the [] operation stands for calls to member functions get() and set(). When compiling to JVM byte codes, the compiler optimizes access to arrays so that there's no overhead introduced, and all operations work exactly like in Java:

val array = array(1, 2, 3, 4) 
array[x] = array[x] * 2 // no actual calls to get() and set() generated 
for (x in array) // no iterator created 

Even when we navigate with an index, it does not introduce any overhead:

for (i in array.indices) // no iterator created 
  array[i] += 2

Finally, in-checks have no overhead either

if (i in array.indices) { // same as (i >= 0 && i < array.size) 

Note: arrays are invariant. For the best performance on the JVM use specialized array classes.

What's next

  • No labels


  1. It would be nice to ignore underscores in integer literals, so 


    could be written as


    Which looks nicer =) the same applies to hex literals which are usually groupped by four hexadecimal digits. I think, even Java plans to introduce this feature.

    1. Thanks for your suggestion. I would like a more general decision than having a hack like this for particular literals, but we'll think about it.

      1. Anonymous

        May i suggest 0c76543210 for octal literals ?

        Also 1_000 is a great help when reading large number literals, also useful for other base literals.

        1. We'd be keen for real life use cases of octal literals. For now it looks like people only use hex and want to use binary.

          1. Anonymous

            My only use for it would be unix file right masks

          2. Anonymous

            NATO data links use a lot of octal's. Aircraft's IFF replies also do.

        2. Anonymous

          Using underscores in numbers is especially useful for binary literals, particularly those which are 'long'-sized.

          I'm not sure what you mean by  "for particular literals"... in Java 7 this will be allowed for all integral types, including floating point numbers. Ruby had it even before Java did.

          See here for an early version of what Java implemented:


    2. Anonymous

      To be specific, this feature will be in Java 7, to be released tomorrow (July 28th).

  2. What about unsigned integers? E.g. should we still use mask-and-cast-magic like (short)(x & 0xff) to get unsigned value of byte?

    1. Yep. But this conversion might be (or even will, in standard library) defined as inline extension function to Byte:

      1. Oh, that's cute, very nice.  But "sht" has got to go, must agree with other commenters that the 3-letter abbreviations for built in types is un-fun.

  3. I would appreciate a full numeric tower, if you can get one in.

    Also helpful would be overflow/underflow detection.

    Love what I'm seeing. 

  4. Anonymous

    I would suggest giving full names to those conversion methods, such that they match type names exactly (except for case); so:

    • 1.byte
    • 1.short
    • 1.int
    • 1.long
    • ...

    Those three-character versions can be tricky to remember for some of the types, and I don't see much reason in making them that short.

    1. There's code completion (smile) But I get your point, we'll think about it.

      BTW, if you don't like these names, you can do something like this:

       val Int.double : Double 
        get() = this.dbl

      And then you can use it:

      1. Will runtime class cast work for this?


        1.asDouble might be better idea than 1.toDouble because of language's `as` keyword.

        Anything is better than `dbl`, really.

        1. A runtime cast will not work.

          Got you point about "as"

        2. Anonymous

          "sht" is not a good idea in English.

      2. Anonymous

        When users start doing that for commonly used features, in order to address deficiencies of the base language, you get "tower of babel" disasters where one user's dialect of the language looks completely unlike another's. For instance, look at what happened to Java before the 'assert' feature was added: there were a zillion incompatible assertion library methods used by various libraries, which made using code from two different libraries very difficult. It is much better if things like this get fixed in the language itself, so everyone is using the same code to do the same thing.

    2. since we still keep .toString as a standard, I vote for 

      1.toLong, 1.toShort, etc...  (just like in Scala)

      really, .lng is much worse than .toLong. Keep in mind that we are going to have first-class IDE support for the language, so no-one would suffer from extra 3 keystrokes, but readablity increases significantly.

      1. Anonymous

        I agree, code is a lot more read than written, and reading "obfuscated" code is painful (as well as writting it, for that matter, because when thinking "long" you'ld have to also think "lng").

        Though, I don't know if it's good to make it look like "toString", because here we want to have THE value as a different type, whereas "toString" can return anything.

    3. +1

      those 3 character abbreviations look ugly & look like obfuscated code. Any of the suggestions in this thread would be good; call the methods "byte(), short() etc" or "asByte(), asShort()" etc. There's a few methods in the JDK already using "asFoo" - e.g. Arrays.asList(....) 

  5. Anonymous

    Are methods "and", "or" and "xor" also provided on booleans?

    It would be neat to have it work like in C#, where & is boolean for bools, and bitwise for ints. Then you could say that "&&" is a short-circuiting AND operator (which, obviously, doesn't make sense for bitwise version), while "and" is a non-short-circuiting version.

    1. There's no decision on this yet, but if there's none, you can make them yourself.

  6. Anonymous

    Are there literals for NaN and signed infinities for floating-point types?

    1. Do we really need literals for those? I suppose properties of Float and Double are quite OK

  7. Anonymous

    Speaking of properties on basic types, I'd like to see some standard predefined constants such as:

    Integer.BITS==32    (In Java this is Integer.SIZE which I think is a less clear name)






    and so forth for the other numeric types. I'd also like to see a lot more basic bit-munging operations on these classes than exist in Java, for instance functions for performing common actions like bitmasking, byte reordering, and such.

  8. Anonymous

    Thank you for pursuing your work on Kotlin.  It looks like it could become a simpler alternative to Java and Scala

    with good development tools and good performance.  That sounds like a good combination for mainstream programmers.

    Please consider providing a simple date-time as a core data type, with a simple literal syntax.  

    Any application dealing with a database would benefit, as well as most other data-oriented applications.

    After years of coding Python, Java and R, that is the one thing I still miss about the old Visual Basic!

    1. This has been brought up a few times already. We'll definitely address this issue, one way or another.

      1. I don't want to over do it.  Would a general mechanism for programmatically defining literals be too much?  You are clever enough with the extension methods and syntax, perhaps you could come up with something similar for parsing literals.  I would be concerned this tends towards "magic" -- code incomprehensible without full knowledge of the source -- but perhaps something reasonable could be done.

      2. Anonymous

        I suggest investigating the date/time libraries of the JSR-310 project and making these, or modified versions of these, integral to the language. A lot of work has been done to make date/time handling statically type-safe (LocalDate vs. OffsetDate, etc.) and to avoid various weird and/or dangerous problems that occur with the java.util.Date and/or java.util.Calendar libraries and their variants. Making these work nicely in Kotlin (operator overloading for comparing dates and/or times of compatible types, but not of incompatible types?) would be a definite plus.

        See http://sourceforge.net/apps/mediawiki/threeten/index.php?title=ThreeTen

  9. Anonymous

    One of Java's mistake (or lets say bad desicion) is that byte type is signed. But if bytes would be unsigned many operations (low level ones especially) would be easier. I would suggest these types:

    byte (unsigned)

    int8, int16, int32, int64, int128 -- all signed

    float32, float64, float128

    naming is consistent and easy to understand.

  10. Anonymous

    Booleans: negation is currently done with "!"

    In http://confluence.jetbrains.net/display/Kotlin/Null-safety?focusedxCommentId=41484560&#comment-41484560 I suggested using another sign for negation. Reason: the way "?" is used in Kotlin -> "!" could then be used for similar purposes. Suggested using "^" for negation.

    Sorry for somehow repeating me, but after some weeks this still appears as a good idea to me, so maybe it is...

    Question is if dropping "!" for negation is "too far away" from Java...

    1. Matlab uses ~ as negation operator. This might be even closer to scientific (hand-written) notation

      1. Anonymous

        ~ is not easily typed from some language-specific keyboards

    2. Dropping ! altogether and using something else for negation would be OK, but using ! for something else seems to be too confusing for people with Java/Scala/C/C++/C# background, which mostly rules that option out.

      1. Anonymous

        "!" in postfix position might not be as bad: "a!" So maybe just avoid "!" in prefix position should be OK for Java/C guys

  11. What about exponentiation? Will we have operator like ** or, at least, build-in function like 5.pow(2) ?

    1. The pow() function will be there. I don't know if we can call it "built-in", because it will simply call the corresponding method from java.lang.Math

  12. Anonymous

    Why not [1, 2, 3] instead of array(1, 2, 3)? Also, why not supporting a map syntax too, like {a: 1, b:2}?

    Rodrigo. (my login name is rosenfeld, but it needs approval from the administrator - how obsolete is this?!)

    1. Hi Rodrigo,

      Introducing syntactic constructs for maps and lists and whatnot seems undesirable from the following standpoints:

      • It's a little too much syntactic constructs
      • It's comparatively little gain
      • It's not self-explanatory:
        • array(1, 2, 3) is obviously an array, but what is this: 1, 2,3 — an array? a list? something else?
        • map(a to 1, b to 2) raises no questions, but {a: 1, b: 2} does
      • It's inflexible: I can't make my 1, 2, 3 create some custom implementation of List
  13. Anonymous


    >So only identity, but even equality

    So not only identity, but even equality

    >numbers are are boxed

    numbers are boxed

  14. I have some questions about the Array class.  They also apply to lists but I can't find anything about the collection classes yet.  Are there plans to support any of the following features from Ruby:

    1. Negative indices for counting from the end: "abcde"[-1] = "e".  This is so much cleaner than str[str.length - 1]
    2. Multiple argument to the get method: get(start, count), so "abcde'"[2, 2] = "cd" or "abcde"[-3, 2] = "cd".  Or maybe get(start, end) to match the behaviour of List.subList()
    3. Ranges as arguments to get: "abcde"[2..3] = "cd"

    It would also be good to have an efficient subArray() method so it's possible to implement a sensible tail() method (or property).

    1. 1. Never heard about this idea. It seems to be rather error-prone (negative indices may appear from various sources)
      2. This is possible to do with an extension function.
      3. Again, an extension function can to that.

      Some of the subList()-like behavior should be included with the standard library, we'll see which is the best.

      1. When I learned Ruby the idea of negative indices seemed weird at first because I was used to the Java way.  But I quickly learned to love them. They give you a very natural way of counting from the end of an array in the same way that positive indices give you a natural way of counting from the beginning.  I also don't think they're particularly error-prone.  How many off-by-one errors have you seen that were caused by developers incorrectly converting from array lengths to indices?  I still have to think for a second in Java when I want the index of the last item.  And methods like String.substring and List.subList where one of the indices is exclusive just make things worse.

        1. Seems like something along the lines of a.getCircular(i) will make things more clear compared to hard-wiring the negative indices into the standard get() function.

          1. That would work for the simple case where you want one item but not if you're using indices to specify a range.  In the palindrome example I created a string by dropping the first and last characters from an existing string

            With negative indices and support for substring() in get() this becomes

            Once you get used to the idea that a negative index means counting from the end I think it's very natural.

    2. In Matlab and Octave there is another syntax for accessing elements from the end:

      So here we use keyword 'end' (it cannot be variable or a function) that means 'maximum element number in inner-most collection'. Semicolon means integer range.

      I think, such approach is better than negative indexes just because it's explicit and unambiguous.

      Although, even if it is possible to define extension function end() that returns this.length-1, use it still not so elegant in Kotlin:

      hello( hello.end - 3, hello.end )

      Sometimes, when you call object's methods, you also need other object's properties. Thus, some kind of implicit 'this' reference might have sense:

      hello( .end - 3, .end )
      hello( #.end - 3, #.end )

      But is not so elegant to justify changes in language syntax and parser.

      So, in the end, my personal vote goes to general-purpose 'takeRight' function (you can see it in Scala), than can be easily implemented over any ordered collection with extension function:

      hello = "hello"; 
      hello.takeRight(3) == "llo"
  15. My first feature wish:

    allow an extra comma in varargs list: e.g.


    This would make array and other initialisation stuff definitions a lot easier to edit.

    1. A rather fresh idea. We need to think about it

  16. Well, java allows it both in enums and array initializers, and it is very convenient, when shifting entries back and forth.

  17. I suppose the resulting array will be a bit different.

    BTW, it would be very convinient having argument list in functions delimited only by spaces, "lisp style".

  18. How to work with Arrays from Java?

    The calling arr[0] shows error, because arr is Java array and it's nullable.
    So, because of null-safety I can't use [] to work with arrays? 

    1. 1. If something is nullable, you have to make sure you are not trying to take an element from a null:

      val arr = ... whatever Java call ... // val is essential here 
      if (arr != null) { 
        val lookAndFeel = arr[0] // works 

      2. If you really want a nullable variable, you can call get() explicitly on your array

  19. Little mistake :

    Every number type supports the following conversions:

    • toLong()toByte() : Byte
    • toShort() : Short
    • toInt() : Int
    • toLong() : Long
    • toFloat() : Float
    • toDouble() : Double
    • toChar() : Char
  20. Is there any easy way to define a two (or more) dimensional array and assign some random value to each index?

    java example:

    1. There's no language support for it. For 2D arrays there should be a wrapper class like "Matrix" in the stdlib, but it is not added yet. This class will support some syntax like this:

      1. Thanks for the reply. It sounds good.

        btw, I used the following existing approach, which is similar to the one described by you, for my case and I think is good enough.

  21. The outcome of following code supposed to be "false" but is "true".  Am I missing something?

    1. Why do you think it should be false?

      1. I guess, "i" and "j" are referring to different objects (a and b) with different addresses.

        by the way, following example, in my pc, prints "false" "false"

        1. I see. Literals are not guaranteed to create new objects each time. In fact, on the JVM we use Integer.valueOf() to create those object, and since that is cached, you get the same instance for values in the range -128..127

          1. thanks for the clarification. but what about the second point?  

            why the outcome of the the first two println methods are "false"

            1. Because 1000 and 10000 do not fall into the range -128..127

              1. sorry, I'm a bit confused. 

                according to definition of identityEquals:

                a identityEquals b : returns true if and only if a and b point to the same objects

                thus for each object a,  a identityEquals a must be always true, regardless of the value that assigned to a.

                1. Ah, I missed your point. I'll explain why this works as is does, but I think we should consider this behavior a bug. The reason is that under the hoods Int is not a reference type: it's represented by a primitive int, but when you are calling identityEquals, who signature is Any?.identityEquals(Any?), it both operands get boxed, and as a result we have two different objects. We'll fix this by introducing overloads of identityEquals for Java primitives.

                  Thanks for pointing this out. Could you file an issue in our tracker?

  22. I think ".int" is replaced by ".toInt()". 

    val i : Int = b.int // OK: explicitly widened

    must be :

    val i : Int = b.toInt() // OK: explicitly widened

  23. Just as a suggestion,

    rename "array()" function to "arrayOf()", to make it consistent with other similar functions (e.g.   "listOf()", "mapOf()").

  24. It has been explained that there is no automatic widening of number types.

    But I still find it confusing that widening occurs on arithmetic, but not on comparison.


            var l: Long = 3
            l = l + 5
            if (l == 5) // not accepted
            var l: Long = 3

            val ll: Long = l + 5 // that ok

            val b: Boolean = l == 5 // not accepted

    Why is one operator treated differently than the other?

    At least being able to write 5l as in Java would help.

    5.toLong() just sucks.

    1. No widening for comparison comes from the fact that comparison means calling equals(), and java.lang.Long.equals(java.lang.Integer) is false.

      We probably should add something like 5.l to the standard library, but the downside is that it looks too much like 5.1

      1. However in Java I can write:

                int i = 4;
                Long L = 4l;
                boolean intEqualsLong = i == L;
                boolean literalIntEqualsLong = 4 == L;

        and both boolean results are true. I believe, that Kotlin could check if an unboxed comparison with widening is possible.

        Orthogonal language design is good, but this case is so frequent, that explicit conversions really bloats the code.

        As a programmer I do not really care if you call equals in the background or do something else alltogether.

        I just want to code as simply as possible.

        1. Your Java example works because Java's boxing/unboxing happens to work fine in this case.

          There are other cases, when it does not:

          Another case:

          Our goal was to avoid such idiosyncratic cases altogether, which we did.

          Plus, Kotlin has no primitives, which makes things a little more risky if you try to employ Java's approach.

          1. I see how java.lang.Long.equals() throws a weird wrench into the picture, but I am not convinced that banning implicit widening conversions is the right path. First, it goes against the grain of what most programmers perceive as reasonable. Second, it is inconsistent with all the widening conversions that occur when using operators.

            You should investigate alternative. Such as:

            - doing implicit conversions almost everywhere except for where it's dangerous (ie, reference function arguments). It may be a little surprising, but a programmer will rarely run into it, and can fix it if the IDE tells him to.

            - have Int equal Java's primitive type, and Int? the boxed version. No conversion from Int? to Long?, plus any other idiosyncrasies specific to boxed types. (Yes, that means no non-nullable boxed primitives. Oh well. Completely erasing the distinction between primitives and boxed primitives is too much for me to grok anyway. I have a feeling it isn't truly possible and will bite me at some point.)

            1. What does "Kotlin has no primitives" Exactly mean?

              What is the Java equivalence to

              is it



  25. In Java, you can perform quite complex string to integer and long conversions like:

    • int n = (int) Long.parseLong("ffff8000", 16);  // this returns a signed integer from a 'signed' Hex string.

    However in Kotlin there does not seem to be a way to pass the radix with the string for conversion.  (Kotlin seems to assume base 10. from .toLong and .toInt)

    While I can call java code to preform these conversions, is there a way to do this more neatly with Kotlin?  If not, is it planned?

    1. I found that the jet libraries were sufficient if i used the following form:

      val test = BigInteger("FFFFFFFFFFFFFFFF",16).longValue();  // evaluates to -1

      1. BigInteger is still a Java class. We are planning to include more of the JDK functionality as Kotlin functions

  26. There're no "L"-tagged or otherwise tagged literals. In case of ambiguity, one should use explicit conversions to specify a type for a literal

    Out of date, I suppose

  27. I really like the fact that conversions are explicit as it puts the responsibility where it belongs: the developer.
    Yet in Numbers.kt there is a definition for every arithmetical type combination, so it's possible to do:

    This is rather implicit. I would rather see a compilation error since I'm trying to multiply different types.
    The implicit operations could be moved to an ImplicitMath extension method package.

    What is the motivation for supporting these types, is it compatibility?

    1. There's always a trade-off: being explicit sometimes means being unnecessarily annoying for the user.
      Being unable to multiply a Double value by 2 is somewhat over the top. But your idea is interesting, we'll think about it.

      1. I suppose some intention in IntelliJ, just like missing imports, can make this far less annoying. But at least it's a developers choice.

  28. Can we haz underscrores in number literals?

    Also, please consider embracing overflow-safe math. Java 8 java.lang.Math provides many functions such as toIntExact, multiplyExact, etc., that you can use to replace the standard unsafe operators and conversion functions.

    1. Overflow-safe math is too expensive to be used by default. You can use all methods from java.lang.Math and write al library DSL for it.

      Underscores in number literals are under considerations

      1. Define too expensive? Overflow checks are a single instruction in x86 asm (JO). In a worst-case microbenchmark http://pastebin.com/VDPJHhQe (no cache hits or misses, no missed branches, etc. which typically keep the processor busy), Math.*Exact was hardly 2x slower. That's not going to be noticeable in most situations, even in many inner loops.

        1. Wow, optional ExactMath would be an amazing addition to the standard library and, I'm sure, a big "sales factor" for Kotlin.

        2. For an operation as common as integer arithmetic, anything over 10% is way too expensive. Also, when writing microbenchmarks, have a look at JMH and friends: http://psy-lob-saw.blogspot.ru/2013/04/writing-java-micro-benchmarks-with-jmh.html

          1. Shouldn't you be a C programmer?

            You can try enabling  checked arithmetic for one of your .NET applications (http://stackoverflow.com/questions/4878548/c-sharp-overflow-not-working-how-to-enable-overflow-checking) to see how much real-world difference it makes. I imagine not much. With judicious use of unchecked {}, there shouldn't be any at all.