Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Java call generic function on generic object

I want to have a method like this

<T> void callFuncOnObj(T obj, Runnable r) {
   obj.r();
   //or
   r.runOnTheInstance(obj);
}

that may be used something like this (ignoring exceptions)

   callFuncOnObj(System.in, InputStream::close);

Obviously, Runnable doesn’t support this. Apparently, the type of InputStream::close is just Object, so how can it be used or even cast so that a generic instance may call it?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

The most obvious alternative I can think of is accepting a Method and dealing with IllegalArgumentException if it doesn’t apply,

void callFuncOnObj(Object obj, Method m) {
   try{
      m.invoke(obj);
   }catch(IllegalArgumentException iae) {
      ...
   }...
}

Is there a good way to do this with generic instances and generic functions on those instances?

>Solution :

There a couple of problems. First, InputStream.close() throws an exception, so it can’t be passed as a Runnable. You can either convert the method reference to a lambda containing a try/catch block, or create a custom parallel interface that allows exceptions:

@FunctionalInterface
interface CustomRunnable {
    void run() throws Exception;
}

The other issue is that Runnable doesn’t accept any arguments. You can pass an instance method reference instead of passing the object separately:

void callFuncOnObj(CustomRunnable r) {
   r.run();
}

Called like this:

callFuncOnObj(System.in::close);

Or you can accept the object with a Consumer (or in this case, a similar interface that allows exceptions) and combine them like this:

<T> void callFuncOnObj(T obj, CustomConsumer<T> c) {
   c.accept(obj);
}

And then your original call would work:

callFuncOnObj(System.in, InputStream::close);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading