Is there in Java 8 any analogue for implements
keyword for methods?
Let's say I have a functional interface:
@FunctionalInterface
interface LongHasher {
int hash(long x);
}
And a library of 3 static methods "implementing" this functional interface:
class LongHashes {
static int xorHash(long x) {
return (int)(x ^ (x >>> 32));
}
static int continuingHash(long x) {
return (int)(x + (x >>> 32));
}
static int randomHash(long x) {
return xorHash(x * 0x5DEECE66DL + 0xBL);
}
}
In the future I want to be able to interchangeably use any of references to these 3 methods as a parameter. For example:
static LongHashMap createHashMap(LongHasher hasher) { ... }
...
public static void main(String[] args) {
LongHashMap map = createHashMap(LongHashes::randomHash);
...
}
How can I ensure at compile time that LongHashes::xorHash
, LongHashes::continuingHash
and LongHashes::randomHash
have the same signature as LongHasher.hash(long x)
?
If we look into some other programming languages such as C++, JavaScript; they are called functional programming language because we can write functions and use them when required. Some of these languages support Object Oriented Programming as well as Functional Programming.
An Interface that contains exactly one abstract method is known as functional interface. It can have any number of default, static methods but can contain only one abstract method. It can also declare methods of object class. Functional Interface is also known as Single Abstract Method Interfaces or SAM Interfaces.
Note that lambda expressions can only be used to implement functional interfaces. In the above example also, the lambda expression implements Consumer Functional Interface. A Java program to demonstrate working of lambda expression with two arguments.
How can we avoid implementing all methods interface in Java? Declare the missing methods abstract in your class. This forces you to declare your class abstract and, as a result, forces you to subclass the class (and implement the missing methods) before you can create any objects.
I had wished for this too, in the past, but no you can't do that. But you know. There was Java before Java 8. Do this instead:
enum LongHashes implements LongHasher {
XOR {
@Override
public int hash(long x) { ... }
},
CONTINUING {
@Override
public int hash(long x) { ... }
},
RANDOM {
@Override
public int hash(long x) { ... }
}
}
And then:
public static void main(String[] args) {
LongHashMap map = createHashMap(LongHashes.RANDOM);
...
}
There's no such syntax construction you're asking for. However you can create a static constant where you explicitly assign the method reference to your interface:
class LongHashes {
private static final LongHasher XOR_HASH = LongHashes::xorHash;
private static final LongHasher CONTINUING_HASH = LongHashes::continuingHash;
private static final LongHasher RANDOM_HASH = LongHashes::randomHash;
static int xorHash(long x) {
return (int)(x ^ (x >>> 32));
}
static int continuingHash(long x) {
return (int)(x + (x >>> 32));
}
static int randomHash(long x) {
return xorHash(x * 0x5DEECE66DL + 0xBL);
}
}
This way your compilation will break if either method signature or interface changes in incompatible way. If you want you may declare them public
and use instead of method references.
If you care that these static lambdas will be hanging in memory at runtime, you can move this declaration to the separate class (for example, nested), which compiles but never loaded.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With