I am trying to 'implement' the following Java interface from JGroups with reify
.
public interface MessageListener extends StateListener {
/**
* Called when a message is received.
* @param msg
*/
void receive(Message msg);
/** Called when a batch of messages is received */
default void receive(MessageBatch batch) {
for(Message msg: batch) {
try {receive(msg);}
catch(Throwable t) {}
}
}
}
In this case the receive method is present twice, with one parameter each (and different types, of course). When I try to reify
with the following code in CIDER:
(reify org.jgroups.MessageListener (receive[#^org.jgroups.Message msg]
(println msg)))
I get an error message:
CompilerException java.lang.IllegalArgumentException: Can't define method not in interfaces: receive, compiling:(*cider-repl clj-groups*:49:21)
As receive
is definitely available in the interface, I assume that this issue is related to the overloaded method and my typ hint is not working. What am I doing wrong?
Edit: After changing the code according to Lees comment:
(reify org.jgroups.MessageListener (receive[this #^org.jgroups.Message msg]
(println msg)))
the error message changed:
CompilerException java.lang.IllegalArgumentException: Mismatched return type: receive, expected: void, had: java.lang.Object, compiling:(*cider-repl clj-groups*:80:21)
Can we overload methods of an interface in Java? Polymorphism is the ability of an object to perform different actions (or, exhibit different behaviors) based on the context. Overloading is one of the mechanisms to achieve polymorphism where a class contains two methods with the same name and different parameters.
In the following example, method addition () is overloaded based on the data type of parameters – We have two methods with the name addition (), one with the parameter of int type and another method with the parameter of string type.
Overloading is the act of defining multiple methods with identical names in the same class. Still, to avoid ambiguity, Java demands that such methods have different signatures in order to be able to tell them apart.
An interface in Java is similar to a class but, it contains only abstract methods and fields which are final and static. Since Java8 static methods and default methods are introduced in interfaces. Default methods − Unlike other abstract methods these are the methods that can have a default implementation.
The following works when you add missing this
argument and hint the return and argument types:
$ boot -d org.jgroups/jgroups:4.0.0.Final repl
(import '(org.jgroups MessageListener Message) '(org.jgroups.util MessageBatch))
;;=> org.jgroups.util.MessageBatch
(def listener
(reify MessageListener
(^void receive [this ^Message msg] (println "Message"))
(^void receive [this ^MessageBatch batch] (println "MessageBatch"))))
;;=> #'boot.user/listener
(.receive listener (Message.))
;; Message
;;=> nil
(.receive listener (MessageBatch. 0))
;; MessageBatch
;;=> nil
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