Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reify Java Interfaces with overloaded method?

Tags:

clojure

reify

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)
like image 765
javahippie Avatar asked Feb 26 '17 20:02

javahippie


People also ask

Can We overload methods of interface in Java?

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.

Is method addition() overloaded in Java?

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.

What is overoverloading in Java?

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.

What is an interface in Java 8?

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.


1 Answers

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
like image 58
Piotrek Bzdyl Avatar answered Sep 24 '22 15:09

Piotrek Bzdyl