Kotlin M12 is out!

We are happy to present Kotlin M12, bringing some rather important changes and new features:

  • New syntax for annotations and enums
  • More convenient semantics of function types
  • Better smart casts
  • kapt for Java Annotation Processing support
  • Multiple IDE features
  • and more…


Many of the changes introduced to the language and core libraries are deprecations. Use “Code Cleanup…” action to fix all warnings in your project automatically.

Annotations: New Syntax

As we mentioned before, we decided to reserve square brackets for some more productive future uses, and make annotation syntax more familiar to Java users. So, since M12, we write @Foo(args) instead of [Foo(args)]. More details can be found here (even more — in the spec document).

Note that @ is not required in most cases. Normally we write annotations without any escaping:

The old syntax based on [...] is deprecated, so the compiler will issue warnings on your code. To fix these warnings, press Alt+Enter and run a quick fix (individual or for the whole project). The aforementioned “Code Cleanup…” action also works for the whole project.

Label Syntax Changed

Since M12 @name is an annotation, but it had a meaning before, i.e. it was a label. We had to find some other syntax for labels, and now they are declared with @ at the end:

So, loop@ declares a label, and break@loop uses it.

Class Literals in Annotations

Before M12, annotations in Kotlin were allowed to use java.lang.Class, for example:

Now, using Java-specific classes is deprecated in Kotlin annotations, and we need to use Kotlin’s own model: kotlin.reflect.KClass instead of java.lang.Class and Foo::class instead of javaClass<Foo>():

Note that Kotlin sees Java annotations as if they referred to KClass instead of java.lang.Class:

Now, when we need to turn a KClass into a java.lang.Class, we can call .java on it, e.g. Foo::class.java or jann.value.java.

Annotated Primary Constructors

We decided to make primary constructor syntax more regular, and now the full form of the primary constructor includes the constructor keyword:

The full form is only needed when we want to annotate a primary constructor or add a modifier. In most cases, the old familiar syntax still works:

Traits Are Now Interfaces

As our traits are rather limited anyways, and Java’s interfaces are pretty much the same thing, we have deprecated the trait keyword, so please use interface instead.

As usual, quick fixes and “Cleanup Code…” will help you along.

Enum Classes: New Syntax

The new syntax for enums is very close to what Java has. Enum entries should now be separated with commas:

Now, when you declare a member of an enum class, it must go after all entries, and there must be a semicolon after the last entry:

Lastly, when enum has a constructor, you can call it by simply passing the arguments next to the name of the entry:

The old syntax is deprecated.

Function Types Reformed

We unified function types and extension function types, so that now they can often be used interchangeably. For example, we can pass String::length where a function '(String) -> Int' is expected.

More details in this post.

If you used Kotlin’s function classes (e.g. kotlin.Function1) in your Java code, you will need to make adjustments to it, because from now on these classes reside in the kotlin.jvm.functions package. You can migrate all your Java code by running “Cleanup Code…” with the “Usage of deprecated function classes in Java” inspection.

Smart Casts Made Even Smarter

A long awaited feature: Kotlin can now smart-cast local var‘s:

Of course, the smart cast only works when the compiler knows that no modification could possibly have happened since the relevant check was made. Note that loops often times distort this picture (due to some technical reasons we can not use a fully-fledged data flow analysis for smart casts), so when a var is mutated in a loop, smart casts may not work.

Usages of public and protected immutable val‘s in the same module can also be smart-cast now:

Inlining and Non-Local Returns Supported for Function Expressions

Function expressions introduced in M11 are now supported in inline calls:

Deprecations and Dropped Features

M12 removes some previously deprecated features:

  • class object is dropped in favor of companion object;
  • init is now required in front of anonymous initializer blocks.

Some more features were deprecated:

Use quick-fixes and “Cleanup Code…” to migrate your programs.

Java Interop


Kotlin has default arguments that dramatically reduce the needs in overloads, but Java clients can not benefit from this feature directly.
In M12 we have added an annotation jvmOverloads that tells the compiler to generate N+1 overloads for a Kotlin function that has N default parameters.
For example,

will generate

Source Maps for Better Debugging (JSR-45)

We can now step through bodies of inlined function, thanks to source mapping tables emitted by the compiler into generated class files.

Some technical notes: every class file has line numbers assigned to instructions. For inlined function bodies we assign line numbers beyond the actual end of file (e.g. if the file has 50 lines, inlined code has line numbers starting with 51), and these “virtual” numbers are mapped to actual sources of the inlined code that possibly reside in other files. The standard JVM debugger understands the source mappings and can step through the appropriate files and lines. The only caveat is that exception stack traces may sometimes contain line numbers beyond the end of file. We are looking for a solution to this problem.

Java Annotations: Argument Ordering

In Java, annotations are interfaces and their parameters are methods of those interfaces. Thus, the ordering of the parameters is insignificant, and the call site can not rely on it. This is why Java requires that all arguments but one (named value) are passed as named.

While annotations declared in Kotlin have proper constructors that admit positioned parameters and even varargs, we can not rely on Java annotations in this respect, so from now on the following applies to Java annotations:

  • only the parameter named value can be passed without a name,
  • only the parameter named value can be a vararg (and automatically becomes one, if it is an array in Java),
  • all other parameters can not be passed as positional.


JavaScript back-end is catching up with the JVM one. M12 adds support for

  • Inlining works between modules
  • Reified parameters
  • Function expressions
  • Secondary constructors


kapt: Annotation Processing (JSR-269)

As mentioned earlier in this post, M12 adds initial support for Annotation Processing, so that frameworks like Dagger 2 work with Kotlin now. The main limitation of the current implementation is that Kotlin code can not refer to any declarations generated by the annotation processors (so, for Dagger you need to write at least one small class in Java).

We are going to fix this limitation in the future by generating stubs for classes emitted by the Kotlin compiler. Details in the aforementioned post.

Gradle: JUnit Support for Android

Kotlin Gradle plugin for Android now supports JUnit tests. All we need to do is follow the standard procedure for Java, but now we can write our tests in Kotlin.

Quasar Support

Some of the recent changes in Kotlin enabled a great addition to our ecosystem: now Quasar provides fibers (lightweight threads), Go-like channels, Erlang-like actors, and other asynchronous tools for Kotlin! See the announcement here.

Standard APIs Changed

M12 adds new functionality to the standard library:

  • new utilities in kotlin.io package
  • new text utilities
  • regular expressions API unified across JVM and JS
  • new collection utilities
  • MIN_VALUE and MAX_VALUE available for all numeric types for both JVM and JS

As we are working on the Kotlin standard library, some things get changed and/or deprecated. Use quick fixes and the “Cleanup Code…” action to migrate your code. (Please make sure that you have attached the sources of the standard library to your project.)

The full list of changes is available here.

IntelliJ IDEA Plugin

Kotlin IDE now supports the standard Introduce Parameter refactoring that turns an expression selected inside a function into a parameter:

Additionally, Introduce Lambda Parameter is available to extract a piece of code as a function value:

Rename has an option to rename related declarations (variables, subclasses etc) as well:

As we are adding a lot of deprecations lately, the IDE now supports ReplaceWith quick-fix: there’s an (optional) extra parameter to the deprecated annotation, where we can specify an expression to replace a deprecated call:

There is an intention action to add ReplaceWith to user’s deprecated declarations.

Some more changes:

  • New Debugger Features
    • Evaluate expression for local functions
    • Field Watch Points (only for properties with backing field)
  • Change Package Intention
  • Highlighting exit points of functions
  • Gutter Marks for recursive calls
  • Unused receiver parameter inspection
  • Code style settings for imports (e.g. we can now always import specified packages with ‘*’)
  • Java2Kotlin Converter now offers to update usages in other files
  • Typing ‘!’ when completion list is open inserts negated call (e.g. !foo.isEmpty())
  • Intention actions to change visibility modifiers
  • Intention actions have much better scope of availability now
  • Quick-fix to add parameters from the base class when the superclass’ constructor has parameters

Things That Haven’t Made It (Yet)

We are still working on some of the changes we announced earlier, such as More Null-safety for Java. Will roll them out as soon as they are ready.

More Announcements Coming

There will be some more M12-related material published in the nearest future. Stay tuned!

About Andrey Breslav

Andrey is the lead language designer of Kotlin at JetBrains.
This entry was posted in Releases. Bookmark the permalink.

47 Responses to Kotlin M12 is out!

  1. Anton says:

    Is there a specific reason why label declaration should include ‘@’ character? You probably could quite successfully use Java syntax for labels, i.e. ‘label:’ – with colon. But maybe I’m missing something?

  2. cypressious says:

    What’s the final syntax for annotation targets? The spec mentions a couple possibilities but none seem to actually work.

    • Thanks, will fix the spec.

      The final syntax is @file:Foo or @file:[Foo Bar]

      • cypressious says:

        I’m sorry, but I’m still confused. My use case is annotating the setter of a delegated property for Dagger2. I need to put @Inject on the setter and @ForDayMonth on the parameter of the setter. Here’s the verbose version without delegation:

  3. Eddie Ringle says:

    I don’t think this is related to M12 specifically, but it appears that the Kotlin Android Gradle plugin does not work with version 1.3.0-beta1 of the Android Gradle plugin that was released yesterday at I/O. I get the following exception when I try to build with both 1.3.0-beta1 and the M12 plugin:

    @Andrey: Just curious, since you’ve deprecated the ‘trait’ keyword, are there any plans to add Rust-style traits to Kotlin, either before 1.0 or beyond? By Rust-style, I guess I mean extending types with entire interfaces at a time, something like:

    public interface HasThing {
    var thing: Thing


    impl HasThing for ExistingClass {
    override var thing: Thing = Thing()


  4. Fritz says:

    Isn’t it about time to release a 1.0? I’ve been following Kotlin for years now and the language seems quite interesting, but I cannot use a language that is not released yet for my company’s products. Any timeframe other than when it’s ready it’s ready?

    • Unfortunately, all we can say for sure is “it’s ready when it’s ready”. You can see how many breaking changes have been made in this milestone, there’s no way something like this can happen to a released language. We are finalizing the language, but it will take us some more time.

  5. M Platvoet says:

    Great work guys, I really like the fact that you dare to reconsider features.

    One of those reconsiderations, so it seems, is that Kotlin now issues a warning
    Package directive doesn’t match file location
    Does this mean that it using non-matching locations isn’t supported anymore in the near future?
    I like the fact that they didn’t have to match as it cuts down on all those “useless” intermediate directories. What is the motivation for this?

  6. Antonio says:

    I have used kotlin now for 3 years and I think is a great language but I am a little bit concerned about the direction the language is taking. For example: is there a reason why you changed the String.split(…) method? Sounds like you are trying to patch some decisions you made in the past. Please advise.

    • We are cleaning up some previously made mistakes. The thing with split() is that we want to make it consistent with the Kotlin motto of making important things explicit: if something creates a complex Regex object, it should be visible in the code, that’s why we are changing the contract of split().

  7. Pingback: Új verzió jelent meg a Java utódjának szánt programozási nyelvből - Hírek - Prog.Hu

  8. Dale King says:

    The addition of the .java for getting the Java class has some issues related to the imports and can fail to compile with a different ordering of imports.

    Start with something like this:

    which adds an import:

    then try auto importing a java class

    val now = Date()

    And use the IDE to select java.util.Date (e.g. alt-enter)

    It will not add an import of java.util.Date, but instead will change that to:

    But that doesn’t compile because it thinks java is referring to the one in reflection.

    You have to manually add the java.util.Date import.

    I can’t seem to reproduce it now, but I thought I saw issues where it would fail to compile if the java.util.Date import was after the java import.

  9. Pingback: Yested FW updated to Kotlin M12 | Yested Framework

  10. Даниил Водопьян says:


    The valueOf() method throws an IllegalArgumentException if the specified name does not match any of the enum constants defined in the class

    Why does it throw an exception rather than make use of kotlin explicit nullability? As I see it, any method that throws exactly one (obvious) exception, which is expected to be handled, should return a nullable value. The benefits are 1) explicitness in the method signature 2) mandatory fail checking 3) shorter user code. It is not the first time I see such a decision in stdlib. Please explain the cons.

    • Not unlike many other things, this is a matter of compatibility with Java: Java’s valueOf() behaves this way, and I don’t think we can alter this behaviour in a sane way

      • Даниил Водопьян says:

        Is it a technical issue (like binary compatibility), or some indulgence for “java-code-copy-pasting”?

        • “Indulgence”? This sounds a little bit too opinionated for a discussion of an engineering decision.

          • Даниил Водопьян says:

            Well, maybe :) Don’t take me wrong – sometimes I disagree with your design decisions, sometimes I am surprised by them. Here I am surprised.

            I am so concerned about that because it is stdlib, and I believe that kotlin stdlib must be as good/sane/elegant as possible.

            Look at Scala – the language may be questionable, but the library sucks, and nothing is more frustrating than that.

            • Dale King says:

              I agree that returning null would be a better API than throwing an exception but that is the API that Java has. There is no getting around the fact that if you call it with an invalid value an exception will get thrown. The only way Kotlin could change that is wrapping the call with a try catch and using a null instead. I don’t think I want Kotlin going that far to change the questionable decision of the Sun API as the default implementation when in reality for most people it really will be an error condition.

              At most I would want them to add a safeValueOf function to request this explicitly or a more fancy implementation would be to figure out if the destination for the value is nullable or not and choose based on that.

              • Даниил Водопьян says:

                @Dale, yes, exactly! But think of this – in Java it was a checked exception, because everybody must check on parsing an input. The closest alternative in Kotlin is a checked null!

  11. Vadzim says:

    I’m using kotlin 0.12.213 and I noticed that my final apk contains a directory with a *.kotlin_class files. And I’m wondering what is the purpose of these files, and why do I need to keep them?

    • Alexander Udalov says:

      Good question. These files are used by Kotlin to figure out what declarations are present in the built-in packages (kotlin, kotlin.reflect) of the Kotlin runtime library which your code was compiled against. They’re useful in exactly two cases: when you’re shipping a library to be used by other Kotlin applications (which is clearly not the case for APK apps), or you’re using Kotlin reflection in your code. If it’s neither, you can safely strip these files from your app.

  12. Dale King says:

    While the annotation processing is great, I have found that one are where Kotlin is safer leads to problems with many uses of annotations. Kotlin properties generate getters and setters with a private field. In an ideal world that is the way things should work and no one outside of the class should be able to access the field.

    But unfortunately, Java has not been so strict and there are many cases of consumers of annotations (both in APT and at runtime) that expect the ability to declare an annotated NON-PRIVATE field. Here are ones that I have seen:

    Luckily dagger2 and Junit rule have a work around with annotating the get/set (which is much clumsier particular when you need qualifiers), but many other libraries don’t have that option.

    Ideally, those libraries would be changed to support annotating get/set methods (and I have requested that on some of them) but that is a long time coming. Unfortunately this leads to difficulties switching to Kotlin.

    What I propose is to add an annotation that can be applied to properties that tells the Kotlin code generator to weaken the encapsulation on the generated backing field to allow access to the raw field from outside the class. This has to be explicitly enabled with the annotation so the default is to make the fields private.

    As other libraries catch on to Kotlin this will be less necessary, but would be a great aid as the world slowly starts supporting Kotlin.

  13. Agustin says:

    Smart cast are not working at all (Using ‘org.jetbrains.kotlin:kotlin-gradle-plugin:0.12.412’) :/

    class A
    protected var mBuffer: ByteBuffer? = null


    • This works as expected: the compiler can’t make sure that mBuffer does not change between the check and the call to capacity(), because another thread could change it, or if the code was a little more complex, another call on the same thread. So, smart casts are unsound for properties, and thus do not work for them. Suggestion: use the let function

      • Aleksandr Dubinsky says:

        Could you explain why we want the compiler to make sure that mBuffer is not changed by another thread? If there is multi-threaded access of mBuffer, then many kinds of statements (such as, if (!mBuffer.isEmpty()) mBuffer.take()) become very dangerous, yet the compiler does not guard us from such things. Why are smart casts different?

        • First of all, it may be changed on the same thread and there’s no way to track that either.

          The type system must guarantee something (in this case that the absence on a NPE at runtime). There’s no such guarantee for the semantics of isEmpty(), because it’s out of the scope of the compiler checks to guarantee complex properties on the library code, but there is one for smart casts, because they are a built-in mechanism in the language.

  14. Vitaliy says:

    As mentioned above traits are deprecated now. And as I can see from Idea help messages specifying a required base class for interface implementations is deprecated too. Are there some possibilities to specifying a required base class now or this functionality will be removed at all?

  15. Vadzim says:

    How can I access a protected field from the superclass written in Java? It gives me ‘Unresolved reference’ error. Tried both this.mField and this.$mField .

    • Works for me. Could you share your code?

      • Vadzim says:

        I’m using ‘0.1-SNAPSHOT’

        class FocusView : View {
        jvmOverloads constructor(context: Context, attrs: AttributeSet, defStyle: Int = 0)
        : super(context, attrs, defStyle) {


  16. Pingback: Roadmap de #kotlin | Kotlin.es

  17. Pingback: Debug logging in Kotlin | Kotlin for Android

Comments are closed.