Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8196445
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 7, 20262026-06-07T05:28:52+00:00 2026-06-07T05:28:52+00:00

I have a process that needs to call a method and return its value.

  • 0

I have a process that needs to call a method and return its value. However, there are several different methods that this process may need to call, depending on the situation. If I could pass the method and its arguments to the process (like in Python), then this would be no problem. However, I don’t know of any way to do this in Java.

Here’s a concrete example. (This example uses Apache ZooKeeper, but you don’t need to know anything about ZooKeeper to understand the example.)

The ZooKeeper object has several methods that will fail if the network goes down. In this case, I always want to retry the method. To make this easy, I made a “BetterZooKeeper” class that inherits the ZooKeeper class, and all of its methods automatically retry on failure.

This is what the code looked like:

public class BetterZooKeeper extends ZooKeeper {

  private void waitForReconnect() {
    // logic
  }

  @Override
  public Stat exists(String path, Watcher watcher) {
    while (true) {
      try {
        return super.exists(path, watcher);
      } catch (KeeperException e) {
        // We will retry.
      }
      waitForReconnect();
    }
  }

  @Override
  public byte[] getData(String path, boolean watch, Stat stat) {
    while (true) {
      try {
        return super.getData(path, watch, stat);
      } catch (KeeperException e) {
        // We will retry.
      }
      waitForReconnect();
    }
  }

  @Override
  public void delete(String path, int version) {
    while (true) {
      try {
        super.delete(path, version);
        return;
      } catch (KeeperException e) {
        // We will retry.
      }
      waitForReconnect();
    }
  }
}

(In the actual program there is much more logic and many more methods that I took out of the example for simplicity.)

We can see that I’m using the same retry logic, but the arguments, method call, and return type are all different for each of the methods.

Here’s what I did to eliminate the duplication of code:

public class BetterZooKeeper extends ZooKeeper {

  private void waitForReconnect() {
    // logic
  }

  @Override
  public Stat exists(final String path, final Watcher watcher) {
    return new RetryableZooKeeperAction<Stat>() {
      @Override
      public Stat action() {
        return BetterZooKeeper.super.exists(path, watcher);
      }
    }.run();
  }

  @Override
  public byte[] getData(final String path, final boolean watch, final Stat stat) {
    return new RetryableZooKeeperAction<byte[]>() {
      @Override
      public byte[] action() {
        return BetterZooKeeper.super.getData(path, watch, stat);
      }
    }.run();
  }

  @Override
  public void delete(final String path, final int version) {
    new RetryableZooKeeperAction<Object>() {
      @Override
      public Object action() {
        BetterZooKeeper.super.delete(path, version);
        return null;
      }
    }.run();
    return;
  }

  private abstract class RetryableZooKeeperAction<T> {

    public abstract T action();

    public final T run() {
      while (true) {
        try {
          return action();
        } catch (KeeperException e) {
          // We will retry.
        }
        waitForReconnect();
      }
    }
  }
}

The RetryableZooKeeperAction is parameterized with the return type of the function. The run() method holds the retry logic, and the action() method is a placeholder for whichever ZooKeeper method needs to be run. Each of the public methods of BetterZooKeeper instantiates an anonymous inner class that is a subclass of the RetryableZooKeeperAction inner class, and it overrides the action() method. The local variables are (strangely enough) implicitly passed to the action() method, which is possible because they are final.

In the end, this approach does work and it does eliminate the duplication of the retry logic. However, it has two major drawbacks: (1) it creates a new object every time a method is called, and (2) it’s ugly and hardly readable. Also I had to workaround the ‘delete’ method which has a void return value.

So, here is my question: is there a better way to do this in Java? This can’t be a totally uncommon task, and other languages (like Python) make it easier by allowing methods to be passed. I suspect there might be a way to do this through reflection, but I haven’t been able to wrap my head around it.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-07T05:28:54+00:00Added an answer on June 7, 2026 at 5:28 am

    This seems (at least to me) to be the “right” Java-esque (or whatever the analog to “Pythonic” is in Java) refactoring. You have properly used the Template Method pattern and your passing of final variables into the inner anonymous subclasses is spot-on and just as the designers of inner classes intended. You have preserved static typing and are using generics well.

    A solution using reflection is indeed possible, but it does sacrifice some static typing niceties and your code will have to catch a few checked exceptions that come with invoking methods, adding some clutter. Reflection is overrated and IMHO not necessary here. We tend to use that in Java more for instrumentation rather than making code easier to read. Wait for Java 8 if you want to pass methods cleanly!

    Also, I do not believe your code is unreadable. Professional Java programmers should be able to read this. Inner classes exist for this type of thing. That said, it is possible to refactor “one more step” and make what are now anonymous classes be named local classes (stil within your methods of course) so your invocation of run() would not be so hard to find. Other than that I have no real refactoring suggestions.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a state machine that needs to call a different method on each
I have a timer that needs to not process its elapsed event handler at
I have written a Scala (2.9.1-1) application that needs to process several million rows
I have a C++ process which has a thread that needs to send floats
I have a multi-process python application (processes are spawned by uwsgi) that needs to
I have Process objects that are monitored from two different views. A Windows.Forms.ListView (actually
I have an xslt stylesheet that needs to call a C# XSLT extension function
I'd like to configure a process that looks something like: Method Call -> Dynamic
I have a method that I call to make web service requests using GET.
I have a process that spawns a helper process. Sometimes I need to debug

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.