Java SE 10: C# Porting Release

Oracle has recently released Java SE 10, and as usual you can find all the requisite information and links on their overview page. This is the first version that follows last year’s accelerated release scheme, with a new major version dropping every six months.

Looking at the final specifications you might well wonder what’s so major about this version. Oracle’s documentation provides the answer: any release containing any addition or removal of Java SE specification features requires a new major version (“feature release”). The new var keyword qualifies, as puny as it seems.

Indeed, Oracle shortened the release cycle for major versions to a mere six months so that small changes to the specification (such as var) could be made more frequently. Java SE 10 should probably have been Java SE 9.1 but that would require allowing specification changes in minor versions, and Oracle won’t do that. So there.

Local Variable Type Inference

At long last Java got type inference for local variable declarations, and with the C# var keyword too, much to the relief of anyone porting C# code to Java (see below). This is probably the least complex feature ever added to the Java language, but Stuart W. Marks’ style guidelines still point out some dangers to be aware of.

Section G6, “Take care when using var with diamond or generic methods,” shows how var dangerously conflicts with Java’s existing generic type inference. If you use both var and omit explicit type parameters on the right-hand side of the variable declaration, those type parameters may be inferred as Object unless an argument provides additional type information.

It’s also worth reading the next section G7, “Take care when using var with literals,” in particular integral numbers. Any such numbers are inferred as int, unless marked as long with the suffix L. Java does not provide any syntax to denote a byte or short literal, so if you want those you must still use explicit types.

2018-04-09: Benji Weber has a fantastic post about representing impractical and impossible (i.e. anonymous) types using var. As in C# this little feature is a lot more powerful than it seems.

Java 10 for C# Programmers

C# got local variable type inference with identical syntax as early as 2007 (C# 3), so it’s in widespread use today. As a consequence one of the more annoying tasks when porting C# code to Java was replacing all those vars with explicit types. No longer having to do this is a substantial benefit, even though var may be just a minor convenience in new Java code.

Incidentally, Java SE 10 has another feature that’s mostly useful for porting C# code: the tag {@summary … } for Javadoc comments. Java used to automatically treat the first sentence of a Javadoc block as its summary, whereas C# XML comments use an explicit <summary> element with arbitrary content. So rewriting XML comments with complex summaries to fit Java’s one-sentence scheme is no longer necessary.

I’ve updated my guide Java for C# Programmers with these points, as well as current links and two other minor notes:

  • Java can automatically unbox primitives from their corresponding wrapper classes. C# has no equivalent functionality because it lacks strongly-typed wrappers. Boxing always uses Object, so unboxing always requires explicit casts.
  • Type bounds for generic type arguments have equivalent functionality but quite different syntax in Java and C#, so I added a brief example. (Java also allows additional interface bounds in cast expressions – did you know?)

Leave a Reply