Future of Java 8 Language Feature Support on Android(android-developers.googleblog.com) |
Future of Java 8 Language Feature Support on Android(android-developers.googleblog.com) |
[1] https://www.scala-lang.org/download/#Software_Requirements
[2] http://stackoverflow.com/questions/35958814/how-jack-java-an...
Is this impression incorrect? Are they doing something special with the Java source code instead of processing the byte code? Are they doing their own javac compiler?
If they aim to translate all valid Java 8 bytecode (and not just classes emitted by javac) then the situation is at least as good as we would have got with Jill.
[1] "Command-line tool to desugar Java 8 constructs that dx doesn't know what to do with, in particular lambdas and method references." https://github.com/bazelbuild/bazel/blob/master/src/tools/an...
Scala is not just a Java with a different syntax. Because of how traits work and because of how they were encoded in Java's class format, in older Scala versions even adding a method with a default implementation breaks binary compatibility, which is why the history of Scala has been so fraught with compatibility breakage.
Scala 2.12 takes advantage of Java 8's new default methods in interfaces, among others, for encoding Scala's features. We finally have a Scala version that isn't so fragile. And because of the limited resources of the core team, they can't maintain different backends.
Java 8 was released in 2014. I cheered for Google when they won Oracle's lawsuit, but when you're forking the ecosystem, you have a responsibility to keep on your promise of keeping up to date and compatible with the upstream. They just pulled a Microsoft and are getting away with it.
Fuck Google for fracturing the Java ecosystem. There, I said it.
Google support for Kotlin, or some initiative to get a grip on security updates are the only announcements that I really want to see about Android at this point: I use an Android phone, but there's no end-user things that I feel that it lacks right now. IMO, the significant weaknesses of the platform are updates and developer experience.
Lack of Java 8 bytecode now, then lack of Java 9 modules tomorrow, and eventually lack of Java 10 value types and improved generics, arrays and JNI replacement.
And of course, lack of many of the SE APIs in any case.
The fun of writing portable libraries between Java and Android Java is only getting better.
To quote the article: "We've decided to add support for Java 8 language features directly into the current javac and dx set of tools."
The way I'm reading that could (maybe) work, the regular toolchain (javac -> .class files -> dx -> dex file) would get an upgraded dx tool that could take classes with Java 8 bytecode as input. In that case something like Scala (or any compiler that outputs Java 8 bytecode classes) would be just as well supported.
https://www.reddit.com/r/androiddev/comments/5zf1xo/future_o...
>I'm guessing the same API restrictions will apply as before? So lambda expressions, method references and type annotations will be available for every API level (so no more retrolambda, or maybe still for try-with-resource?), but other Java 8 features like default and static interface methods and streams are still only for 24 and up?
>>Yes, this is correct -- we are currently matching Jack's feature set. That means that we support lambdas, method references, type annotations, and repeated annotations for every API level; default and static interface methods are only supported for 24 and up. We are still not supporting try-with-resources below API 19. Java 8 APIs still depend on the API level since those are included with the OS (sadly, this means no java.time). For anyone interested, the source code for the Java 8 compatibility tool, which we call Desugar, is here:
https://github.com/bazelbuild/bazel/tree/master/src/tools/an...
...I hope they fix IntelliJ's default suggestions, which try to turn all of your loops into `.stream()` calls!
This is about the toolchain. The standard Android toolchain uses standard OpenJDK/Oracle JDK Java compiler to compile your app code into standard java class files and then uses dex tool to translate that bytecode into Dalvik/ART DEX bytecode.
Jack toolchain was all about replacing this javac -> dex step with a single fast compiler which would also support more Java 8 features and translate them into DEX format while taking into account feature limitations of ART/Dalvik runtime. The downside was that it didn't support bytecode manipulation tools (tools that work on Java class files before they're translated into dex format) and annotation code generators. Since a lot of good Android libraries rely on annotation generation that was a pretty huge deal breaker.
This news is about Google abandoning the Jack project and retrofitting the improvements and partial Java 8 feature support into current toolchain.
Presumably they could have the dx tool in the current toolchain support Java 8 bytecode .class files as input (just as the Jill linker in Jack toolchain allows).
>I thought the whole rationale for Jack was it was a clean break from Sun / Oracle Java and entirely open source.
In the current toolchain you do something like the following: java sources -> javac -> .class files -> dx tool -> dex file -> ...
(We already have an open javac with OpenJDK by the way, and dx is part of AOSP, so "entirely open source" was essentially solved).
Part of the idea behind Jack was that by creating a new compiler toolchain specifically for Android you could have a faster build by jettisoning the unnecessary .class intermediates and going straight to dex from the sources (or rather, as it turns out, a pre-dex that goes into a new intermediate .jack file with other metadata).
Jack broke a lot of things on Android (like some annotation libraries, which the article mentions), so I think the wider Android community will be happy there's a clear path forward to Java 8.
While Kotlin is nowhere to be seen on Android SDK and Google is officially silent on its use.
This matters a lot to customers IT departments, writing the set of delivery languages on their Requests For Proposal to consulting companies.
http://scade.io or chat slack channel perfect.ly to chat with the team.
I'm assuming they'll translate bytecode for older API versions? Or will Java 8 only be available for newer API versions?
See https://www.reddit.com/r/androiddev/comments/5zf1xo/future_o...
Also, if looking for APIs, and willing to risk having to tweak code later, there are a few "polyfills". For example: https://www.google.ca/amp/s/barta.me/enable-java-8-features-...
http://www.cydiasubstrate.com/id/727f62ed-69d3-4956-86b2-bc0...
Dalvik is the main reason why Android became so popular.
(Yes, it would be nice if new Android versions would expand the standard library).
In the end I don't see that as a huge restriction - instead of java.time there's ThreetenABP, instead of streams there's better RxJava, etc. With added bonus that you're not limited to whatever libraries device ships with, but you bring your own always up to date ones.
Also, right now, any new project should pretty much be started in Kotlin which does everything that Java 8 does better and is bytecode compatible with Android VMs.
If it is suggesting it on a correctly configured Android project, I suspect you found a bug.
Xamarin looks a nice proposal out of this mess and as a JVM/.NET/C++ consultant, with focus on native apps, I have been looking into it as possible alternative.
2) interesting. I wasn't aware of these. It would have been useful to get sun involved in the project, but they didn't.
(We're running Kotlin in production for a long while now and at this point I think starting development of an app in Java is rather silly considering how stable and nice Kotlin is.)
Kotlin is full interoperable with Java APIs and libraries and at this point there's really very few cases where it's not a significantly better choice for Android development.
It won't, that's what they addressed in this post by ditching jack and switching back to javac bytecode.
"Over time, we realized the cost of switching to Jack was too high for our community when we considered the annotation processors, bytecode analyzers and rewriters impacted."
Why should Google be a special snowflake that doesn't play by the same rules?
Second, Oracle has explicitly said that OpenJDK is OK, and Google has shifted to an implementation based on OpenJDK.
So I wouldn't hold my breath for your prediction coming true...
No they have not, just go look at AOSP source code.
Yes they are using it instead of Harmony nowadays, but they are cherry picking features and APIs, instead of providing 100% compatibility with the language standard.
Kotlin is Java done much better. Null as syntax, extensions with receivers, reified typing, type-safe builders, first-class lambdas, sealed classes, co-routines and so much more...
Kotlin is my language of choice for just about everything at the moment.
I have done 15+ years of programming in Java (Desktop, Server, Android), JavaScript (ES5, ES6+), Kotlin and a little programming in Coffee-script. Your comparison is just wrong.
It's 100% compatible to Java so of course it's not a completely different language. Haskell is a different language. I like Haskell, but I'm glad that I don't have to convert all my old java code to it.
I can open old java-projects and use Kotlin on a file-by-file basis without any problems.
> It's 100% compatible to Java so of course it's not a completely different language. Haskell is a different language. I like Haskell, but I'm glad that I don't have to convert all my old java code to it.
> I can open old java-projects and use Kotlin on a file-by-file basis without any problems.
Sure. I do exactly that in Scala too.
The "extension methods" in Kotlin (and C#) is a completely different feature: syntactic sugar for static utility methods, which allow you to add new methods to any class without needing to modify the original class. (Or at least make it look that way syntactically.)
So in Kotlin you can do this:
fun String.toLeetSpeak(): String {
val charmap = mapOf('e' to '3', 'l' to '1')
return this.map { charmap[it] ?: it }.joinToString(separator="")
}
fun main(args: Array<String>) {
println("Hello!".toLeetSpeak())
}
...whereas in Java you would have to change (and have access to) the implementation of one of the classes or interfaces that String inherits from.In my code null-pointer exceptions or similar accidents (force unwrapping something that simply doesn't exist) never happens anymore. Not in my libraries and not in my program code. A whole class of bugs just gone. Simply because I have to prove that something exists before I use it at compile time already.
It's like having security that starts with everything turned OFF for a default user instead of ON.
Optionals of Java8 and Guava are a terrible idea. @Nullable is just an annotation. Null-safety built in the language is the only way to go.
You could always argue that a language is just cleaner syntax. Kotlin is a cleaner syntax for interacting with JVM-bytecode. Scala is a also cleaner syntax for interacting with JVM-bytecode. JVM-Bytecode is a cleaner syntax for interacting with operating systems.
Right on the spot, yet as Silicon Valley darling they get a free pass instead of being blamed like Microsoft was.
I still hope Oracle manages to force them to play by rules.
Other JVM vendors like IBM, Atego, Azul, MicroEJ,.... are able to provide their own extensions, while supporting Java properly and not forking the whole language + standard libraries.
Some of them do sell JVMs for embedded devices with soft and real-time constraints much higher than Android, so the whole story about a Java fork being a requirement for Android is such Google marketing for their actions.
Kotlin is a smaller language than Java (just based on my feeling actually) yet more safe and in many regards flexible. Kotlin is more similar to Swift, where Swift is aimed at Cocoa and Kotlin at the JVM.
The only thing it really has in common is that it uses the JVM. But F# is not similar to C# just because it has .Net compatibility. Especially if you try to write C# in F# instead of F# according to the gospel.
Just as I've seen tons of code by Objective-C devs that's just the old code translated to the new code a lot of Java devs probably won't really get Kotlin and will write the same code as they would do in Java.
Apparently every other commercial JVM vendor doesn't have any issue to comply with licenses, while offering their own changes to Java stack.
IBM, MicroEJ, Atego, just to cite three examples out of many.
Just search for "Google slimmed Sun".
Specifically, call by name is highlighted in the IDE these days (though I agree we would be better off without it), implicit parameters are really important and it's not hard to ensure consistency, for comprehension is the opposite of what that site is saying (dealing with multiple monads is a lot harder without it, and it's not like ignoring monads as Kotlin does makes the problems you need monads for go away), and the rule about operators is incredibly simple (your method name is just your method name, if you want to write a "" operator you call it "" rather than having to remember what the magic name for overloading that is).
Meanwhile your link ignores the many complex features in Kotlin e.g. delegation, platform types. Maybe they were added since it was written - Kotlin seems to add a lot of ad-hoc features very quickly.
The microbenchmark in the blog post ran in 922 milliseconds on the Google G1 (a.k.a. HTC Dream), or 520 without the assignment in the loop. On my K800i the corresponding numbers were 190–220 ms and 135–165 ms – although I had to scale the size of the buffer down from 1228800 to 1100000 elements due to lack of memory, but scaling the results up by that factor the K800i was still 3–4 times as fast as the G1.
Hardware-wise the G1 should have been much faster. It had an ARM11 at 528 MHz and the K800i had (I think) an ARM9 at somewhere around or below 200 MHz.
[1] http://web.archive.org/web/20091123074004/http://occipital.c...
The fact that you can use a lot of standard Java libs with Android was and is a huge boon that makes development significantly easier than the hell that was JavaMe.
Android fragmentation is no different than J2ME used to be.
1. Price - you can buy an unlocked Android device for $50.
2. It is free to manufacturers
3. No alternative for phone manufacturers at first. By the time Windows Phone git good enough, it was too late.
Every other commercial Java vendor in this planet doesn't have any issue using standard Java tools, compiling with Java licenses and deliver JVMs able to run in embedded devices with soft and hard real time constraints.
Google for all their might is a special snowflake not able to do what the rest of the Java world is capable of.
(Actually, the current court ruling is that APIs can be copyrighted, but re-implementing them is fair use. My personal IANAL opinion is that that won't stand - it will either turn into "APIs can't be copyrighted" or else into "APIs can be copyrighted, and the copyrights are not worthless - you can't copy it and have it be fair use". We shall see. Nevertheless, at the time Google copied the API, the assumption in the whole industry was that an API could not be copyrighted. Your statement that Google "wanting their cake for free" carries a tone of moral criticism that is unwarranted by the circumstances.)
class Dictionary {
val wordList = setOf<String>()
fun String.isWord(word): Boolean =
word in wordList
}
...
val myDictionary = Dictionary()
with (Dictionary) {
println("dog".isWord)
}
(you can skip the "with" when being inside Dictionary)Or, you know, just define a plain function.
> which allow you to add new methods to any class without needing to modify the original class
No, those aren't methods, because they don't do dynamic dispatch. This is actually a problem in case you have an inheritance hierarchy and you want different behavior for a ChildClass extending a BaseClass.
Speaking of Scala, it's the only one out of the ones mentioned here that can do that based on the compile-time time, by letting you define the same extension for both ChildClass and BaseClass, but with different priorities, such that the compiler can disambiguate.
My comment was about extension methods and how the name refers to different features in Java and Kotlin, so I meant "...whereas in Java [if you wanted to use the Java feature to do the same thing the Kotlin feature by the same name does] you would have to ...".
> those aren't methods
I know, they're only sugar for static methods, as I said.
Once you start interacting with JVM bytecode Kotlin ceases to have null-safety. @Nullable is just an annotation but at least you can write it down, unlike Kotlin's "platform types". Conversely if you're not interacting with non-Scala bytecode then Scala is null-safe in practice if not in theory, because the Scala ecosystem doesn't use null and has tools to enforce this.
A variable being null is not a condition you can always a have a name for. You want to use it sometimes, but not built your entire vocabulary around it.
You also don't usually want to pass wrapped nulls around, you just want nulls available in local state.
Sure, which is why it should be an ordinary library type written in the language (and operated on with normal methods), not a magic special type with direct compiler support and custom operators.
> A variable being null is not a condition you can always a have a name for. You want to use it sometimes, but not built your entire vocabulary around it.
> You also don't usually want to pass wrapped nulls around, you just want nulls available in local state.
Why are you thinking in terms of "null" and "wrapping"? Think in terms of the business condition you want to represent. Often you have the possibility of some value being not-set or unknown in your data model - this comes up often enough that it's worth having a standard library type to represent it. "A variable being null" is not something that happens a priori, it's just an unfortunate representation certain languages adopt.
They are not more reified than what you can achieve by just putting Class<T> fields in Java objects to represent the runtime type of the generic type parameter. Sure, Java solution is kinda more verbose and ugly, but this is basically what people already said here: Kotlin has some nice syntax sugar.
But you still can't have two different methods differing only with the generic type parameter (e.g. List<String> and List<Integer>). And the code is still not-specialized properly, read "slow".
Real reification will be possible if project Valhalla arrives (maybe Java 10, who knows?)
That has to be hyperbole: no one who ported J2ME apps would say what you did with a straight face. Even a run-of-the-mill app with no esoteric features would need to be ported because Nokia's methods had different signatures to SonyEricsson's for text fucking rendering, because why not. The entirety of J2ME an "OEM specific SDK" This is before considering MIDP, CLDC versions and goddamn model-specific processor and memory differences. "Android fragmentation is no different than J2ME used to be" my ass.
> no one who ported J2ME apps would say what you did with a straight face. > This is before considering MIDP, CLDC versions and goddamn model-specific processor and memory differences. "Android fragmentation is no different than J2ME used to be" my ass.
How is Android any different? Should I start listing differences among devices here?
This is a huge overstatement. J2ME was fragmented in things like basic UI with no tooling to handle it. In Android you really need to dig into hardware-specific funcionality (or really really mess up UI design) to be severely affected by the fragmentation.