views:

11571

answers:

11

I have a method that's about 10 lines of code. I want to create more methods that do the exact same thing except for a calculation that's going to change one line of code. This is a perfect application for passing in a function pointer to replace that one line, but Java doesn't have function pointers. What's my best alternative?

+83  A: 

Anonymous inner class

Say you want to have a function passed in with a String param that returns an int. First you define an interface with the function as its only member, if you can't reuse an existing one.

interface StringFunction {
  int function(String param);
}

A method that takes the pointer would just accept StringFunction instance like so:

public void takingMethod(StringFunction sf) {
   //stuff
   int output = sf.function(input);
   // more stuff
}

And would be called like so:

ref.takingMethod(new StringFunction() {
  public int function(String param) {
    //body
  }
});
sblundy
In that case it would have to be new ParentClass.StringFunction() if its an inner class and you are not calling it from inside the parent class.Anyways, I Think it doest have to be an INNER anonymous class, just an annnymous one
Pablo Fernandez
It doesn't need to be anonymous at all. You can re-use these 'functions', or provide slots for data in the class to get something similar to a closure, or static method variables.
rcreswick
Real programmers don't even bother with the interface. They just return an anonymous inner subclass of Object that overrides toString(), and parse the returned String to get what they want.Shoot; nobody can mod me +1, Funny here. :) Oh, well. I'm probably not, anyway.
skiphoppy
@skiphoppy but, this wasn't a Python question.. ;)
rcreswick
This is an example of the "Command Patern", by the way. http://en.wikipedia.org/wiki/Command_Pattern
Ogre Psalm33
Anonymous inner classes are like anonymous functions, which is a special case of a function object (a literal). Function pointers rather correspond to a type, so in Java that would be an interface.
starblue
@Ogre: First class functions in a lexically scope language were introduced in the 1960s with Algol, then encouraged and taught in 1985 with the textbook Structure and Interpretation of Computer Programs (Lisp dialect of Scheme, late 1970s). Design patterns in OOP were introduced in the late 1980s. It's good that eventually this stuff goes mainstream, even if for some reason a name change is necessary.
Jared Updike
The need to do it in such a complex and convoluted way makes me sick :(
Lo'oris
+18  A: 

For each "function pointer", I'd create a small functor class that implements your calculation. Define an interface that all the classes will implement, and pass instances of those objects into your larger function. This is a combination of the "command pattern", and "strategy pattern".

@sblundy's example is good.

Blair Conrad
+12  A: 

You need to create an interface that provides the function(s) that you want to pass around. eg:

/**
 * A simple interface to wrap up a function of one argument.
 * 
 * @author rcreswick
 *
 */
public interface Function1<S, T> {

   /**
    * Evaluates this function on it's arguments.
    * 
    * @param a The first argument.
    * @return The result.
    */
   public S eval(T a);

}

Then, when you need to pass a function, you can implement that interface:

List<Integer> result = CollectionUtilities.map(list,
        new Function1<Integer, Integer>() {
           @Override
           public Integer eval(Integer a) {
              return a * a;
           }
        });

Finally, the map function uses the passed in Function1 as follows:

   public static <K,R,S,T> Map<K, R> zipWith(Function2<R,S,T> fn, 
         Map<K, S> m1, Map<K, T> m2, Map<K, R> results){
      Set<K> keySet = new HashSet<K>();
      keySet.addAll(m1.keySet());
      keySet.addAll(m2.keySet());

      results.clear();

      for (K key : keySet) {
         results.put(key, fn.eval(m1.get(key), m2.get(key)));
      }
      return results;
   }

You can often use Runnable instead of your own interface if you don't need to pass in parameters, or you can use various other techniques to make the param count less "fixed" but it's usually a trade-off with type safety. (Or you can override the constructor for your function object to pass in the params that way.. there are lots of approaches, and some work better in certain circumstances.)

rcreswick
+7  A: 

You may also be interested to hear about work going on for Java 7 involving closures:

What’s the current state of closures in Java?

http://gafter.blogspot.com/2006/08/closures-for-java.html
http://tech.puredanger.com/java7/#closures

Dave L.
+1 for useful links, even though I think that adding closures to Java is completely unhelpful.
mikera
+1  A: 

Sounds like a strategy pattern to me. Check out fluffycat.com Java patterns.

Dennis S
+6  A: 

You can also do this (which in some RARE occasions makes sense). The issue (and it is a big issue) is that you lose all the typesafety of using a class/interface and you have to deal with the case where the method does not exist.

It does have the "benefit" that you can ignore access restrictions and call private methods (not shown in the example, but you can call methods that the compiler would normally not let you call).

Again, it is a rare case that this makes sense, but on those occasions it is a nice tool to have.

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

class Main
{
    public static void main(final String[] argv)
        throws NoSuchMethodException,
               IllegalAccessException,
               IllegalArgumentException,
               InvocationTargetException
    {
        final String methodName;
        final Method method;
        final Main   main;

        main = new Main();

        if(argv.length == 0)
        {
            methodName = "foo";
        }
        else
        {
            methodName = "bar";
        }

        method = Main.class.getDeclaredMethod(methodName, int.class);

        main.car(method, 42);
    }

    private void foo(final int x)
    {
        System.out.println("foo: " + x);
    }

    private void bar(final int x)
    {
        System.out.println("bar: " + x);
    }

    private void car(final Method method,
                     final int    val)
        throws IllegalAccessException,
               IllegalArgumentException,
               InvocationTargetException
    {
        method.invoke(this, val);
    }
}
TofuBeer
I use this for menu handling/GUIs sometimes because method syntax is so much simpler than anonymous inner class syntax. It's neat, but you are adding the complexity of reflection which some people don't want to dig into, so be damn sure you get it right and have clear, textual errors for every possible error condition.
Bill K
+2  A: 

If you have just one line which is different you could add a parameter such as a flag and a if(flag) statement which calls one line or the other.

Peter Lawrey
+1 because sometimes that is just enough.
javashlook
+4  A: 

When there is a predefined number of different calculations you can do in that one line, using an enum is a quick, yet clear way to implement a strategy pattern.

public enum Operation {
    PLUS {
        public double calc(double a, double b) {
            return a + b;
        }
    },
    TIMES {
        public double calc(double a, double b) {
            return a * b;
        }
    }
     ...

     public abstract double calc(double a, double b);
}

Obviously, the strategy method declaration, as well as exactly one instance of each implementation are all defined in a single class/file.

javashlook
A: 

Check out lambdaj

http://code.google.com/p/lambdaj/

and in particular its new closure feature

http://code.google.com/p/lambdaj/wiki/Closures

and you will find a very readable way to define closure or function pointer without creating meaningless interface or use ugly inner classes

Mario Fusco
+1  A: 

One of the things I really miss when programming in Java is function callbacks. One situation where the need for these kept presenting itself was in recursively processing hierarchies where you want to perform some specific action for each item. Like walking a directory tree, or processing a data structure. The minimalist inside me hates having to define an interface and then an implementation for each specific case.

One day I found myself wondering why not? We have method pointers - the Method object. With optimizing JIT compilers, reflective invocation really doesn't carry a huge performance penalty anymore. And besides next to, say, copying a file from one location to another, the cost of the reflected method invocation pales into insignificance.

As I thought more about it, I realized that a callback in the OOP paradigm requires binding an object and a method together - enter the Callback object.

Check out my reflection based solution for Callbacks in Java. Free for any use.

Software Monkey
+1  A: 

@sblundy's answer is great, but anonymous inner classes have two small flaws, the primary being that they tend not to be reusable and the secondary is a bulky syntax.

The nice thing is that his pattern expands into full classes without any change in the main class (the one performing the calculations).

When you instantiate a new class you can pass parameters into that class which can act as constants in your equation--so if one of your inner classes look like this:

f(x,y)=x*y

but sometimes you need one that is:

f(x,y)=x*y*2

and maybe a third that is:

f(x,y)=x*y/2

rather than making two anonymous inner classes or adding a "passthrough" parameter, you can make a single ACTUAL class that you instantiate as:

InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f=new InnerFunc(2.0);// for the second
calculateUsing(f);
f=new InnerFunc(0.5);// for the third
calculateUsing(f);

It would simply store the constant in the class and use it in the method specified in the interface.

In fact, if KNOW that your function won't be stored/reused, you could do this:

InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f.setConstant(2.0);
calculateUsing(f);
f.setConstant(0.5);
calculateUsing(f);

But immutable classes are safer--I can't come up with a justification to make a class like this mutable.

I really only post this because I cringe whenever I hear anonymous inner class--I've seen a lot of redundant code that was "Required" because the first thing the programmer did was go anonymous when he should have used an actual class and never rethought his decision.

Bill K