We’re Taking Bets: This Annotation Will Soon Show up in the JDK
This recent Stack Overflow question by Yahor has intrigued me: How to ensure at Java 8 compile time that a method signature “implements” a functional interface. It’s a very good question. Let’s assume the following nominal type:
@FunctionalInterface interface LongHasher { int hash(long x); }
The type imposes a crystal clear contract. Implementors must provide a single method named hash()
taking a long
argument, returning a int
value. When using lambdas or method references, then the hash()
method name is no longer relevant, and the structural type long -> int
will be sufficient.
In his question, Yahor wants to enforce the above type upon three static methods (example modified by me):
class LongHashes { // OK static int xorHash(long x) { return (int)(x ^ (x >>> 32)); } // OK static int continuingHash(long x) { return (int)(x + (x >>> 32)); } // Yikes static int randomHash(NotLong x) { return xorHash(x * 0x5DEECE66DL + 0xBL); } }
And he would like the Java compiler to complain in the third case, as the randomHash()
does not “conform” to LongHasher
.
A compilation error is easy to produce, of course, by actually assigning the static
methods in their functional notation (method references) to a LongHasher
instance:
// OK LongHasher good = LongHashes::xorHash; LongHasher alsoGood = LongHashes::continuingHash; // Yikes LongHasher ouch = LongHashes::randomHash;
But that’s not as concise as it could / should be. The type constraint should be imposed directly on the static
method.
And what’s the Java way of doing that?
With annotations, of course!
I’m going to take bets that the following pattern will show up by JDK 10:
class LongHashes { // Compiles @ReferenceableAs(LongHasher.class) static int xorHash(long x) { return (int)(x ^ (x >>> 32)); } // Compiles @ReferenceableAs(LongHasher.class) static int continuingHash(long x) { return (int)(x + (x >>> 32)); } // Doesn't compile @ReferenceableAs(LongHasher.class) static int randomHash(NotLong x) { return xorHash(x * 0x5DEECE66DL + 0xBL); } }
In fact, you could already implement such an annotation today, and write your own annotation processor (or JSR-308 checker) to validate these methods. Looking forward to yet another great annotation!
So, who’s in for the bet that we’ll have this annotation by JDK 10?
Reference: | We’re Taking Bets: This Annotation Will Soon Show up in the JDK from our JCG partner Lukas Eder at the JAVA, SQL, AND JOOQ blog. |
We need more programming in Ada. 90% of programming errors come out at compile time using Ada.
I program in C/C++, Java, Python, and have done Ada in the past.
Seriously Ada is likely the most reliable programming and fault tolerant languages.
Let’s do it!!!
I’ve always liked Ada, so why not?
Rather than betting on the appearance of this annotation I would bet that some time soon annotations will be frowned upon. They are are a hack, a workaround for missing compiler features and are being misused to replace XML programming (aka “configuration”).
Sounds like you got that idea from here: http://www.annotatiomania.com :)