tags:

views:

651

answers:

11

I've come across some code that I can't share here but it declares a method WITHIN the paramter list of another method. I didnt even know that was possible. I dont really understand why its doing that. Can someone please explain to me some possible uses that you as a programmer would have for doing that? (Note: Since I can't show the code I dont expect an in-context explanation just generally)

Related:

What's the nearest substitute for a function pointer in Java?

+4  A: 

In Java you can't pass methods as parameters. Could it have been passing not a method, but an anonymnous inner class?

This can be useful for passing behaviours between classes. Google "dependency injection" or "Inversion of control" for more information.

Im pretty sure it isnt an anonymous inner class because it starts with public void name() {} etc
Diego
Well, technically, you could pass a Method object.
Chris Kessel
A: 

this is called reflection. there is a whole library of objects representing stuff like constructors, methods and such.
you can use it, for instance, in order to call a dynamic method that is determined on runtime.

Amir Arad
+1  A: 

It's not, per se, legal syntax in Java. Was it perhaps creating a new instance of an anonymous class?

Steve McLeod
+3  A: 

using java.lang.reflect.Method

example

public void callMethod(Method aMethod, int value) throws Exception {
    aMethod.invoke(this, value);
}

public void print(Integer value) {
    System.out.print(value);
}

public void println(Integer value) {
    System.out.println(value);
}

public void demo() throws Exception {
    Method println = this.getClass().getMethod("println", Integer.class);
    Method print = this.getClass().getMethod("print", Integer.class);
    callMethod(println, 10);
    callMethod(print, 10);
}
dfa
I've seen this before online. People say its reflection, some people say it isnt possible, people say it IS possible, because of reflection.
Diego
You can use reflection to pass a Method object as a parameter, but you cannot use to to DECLARE a method, which is what you say your code does.
Michael Borgwardt
+17  A: 

Did the code look something like this?

obj.someMethod(myVar,3,new FooObject() {
  public void bar() {
    return "baz";
  }
});

If so, then the method is not being passed to the other method as an argument, but rather an anonymous inner class is being created, and an instance of that class is being passed as the argument.

In the example above FooObject is an abstract class which doesn't implement the bar() method. Instead of creating a private class that extends FooObject we create an instance of the abstract class and provide the implementation of the abstract method in line with the rest of the code.

You can't create an instance of an abstract class so we have to provide the missing method to create a complete class defintion. As this new class is created on the fly it has no name, hence anonymous. As it's defined inside another class it's an anonymous inner class.

It can be a very handy shortcut, especially for Listener classes, but it can make your code hard to follow if you get carried away and the in line method definitions get too long.

Dave Webb
Kind of like that actually except FooObject is actually an abstract class that already exists elsewhere so it isnt an anonymous inner class right?
Diego
Yes, it would be anonymous, with the parent class of the anonymous one being FooObject.
Daniel Schneller
Im starting to think you're probably right. However, what about others saying that its possible through reflection?
Diego
if the passed in object is of type Method, then yes, then it is being done through reflection.
Chii
A: 

Yes, declaration of a method within the parameter list of another method can be done. You can check out java.lang.reflect.Method

Using reflection, you retrieve a Method object representing the method you wish to pass as a parameter. Then you can call Method to invoke to make a call to that method.

Moreover, you can refer "Functional programming in the Java language" (http ://www.ibm.com/developerworks/java/library/j-fp.html) which can give you inside-out with examples.

Green Techy
See? Im confused! Is it reflection or an anonymous inner class?
Diego
A: 

The answers above are varying as to whether or not it is even possible. Is it possible through reflection? Is possible through the use of an anonymous inner class? We need to clarify this.

Diego
If you show the syntax (you don't have to show the exact code), it's easier to understand what you mean.
Björn
the question is slightly ambiguous in that the word 'method' has an overloaded meaning: 1) the java reflection type called Method (http://java.sun.com/javase/6/docs/api/java/lang/reflect/Method.html ), which is a type that can be passed around like any other type, and 2) what you wrote '...it declares a method WITHIN the paramter list...' , the proper term for that is declaring an anonymous inner class. Its hard to tell which one you mean exactly. You can achieve passing in 'methods' in many ways, and this is two of them. what is your exact question?
Chii
Well, what do you expect when you ask a question about code without showing that code?
Michael Borgwardt
@Diego: It is possible using EITHER reflection (as shown here: http://stackoverflow.com/questions/887444/java-methods-taking-a-method-as-an-argument/887461#887461) OR using an anonymous inner class (as shown here: http://stackoverflow.com/questions/887444/java-methods-taking-a-method-as-an-argument/887477#887477). Which one does this code look like?
Grant Wagner
+1  A: 

You can also do something like this:

final Predicate somePredicate = new Predicate<Item>() 
  {
  @Override
  public boolean apply(Item item)
    {
    return item.someProperty().equals(something);
    }
  }

And use it like this:

List<Item> filteredList = filter(list, somePredicate);

I've done stuff like that before. I've also written methods that use a closure to build and return an anonymous implementation of an interface in a similar way:

Predicate isSomeColor(final Color color)
  {
  return new Predicate<Shape>() 
    {
    @Override
    public boolean apply(Shape shape)
      {
      return shape.getColor().equals(color);
      }
    }
  }

List<Shape> redShapes = filter(shapes, isSomeColor(Color.RED);

All of this is still anonymous inner classes. Nowhere am I actually naming the class itself, I just have a reference to an instance of the class.

Adam Jaskiewicz
+1  A: 

The nearest thing to passing a function pointer in Java is passing an anonymous instance of an abstract class or interface. For example, a generic function type can be encoded in an interface like this:

public interface F<A, B> {
  public B f(final A a);
}

You can then expect a method in another method's argument list:

public List<B> map(List<A> as, F<A, B> f) {
  ...
}

And you can call it with an anonymous instance of that interface:

map(myList, new F<Integer, String>() {
  public String f(Integer i) {
    return String.valueOf(i);
  }
});

There's a library called Functional Java that exploits exactly this idea for great benefit glorious language Java.

Apocalisp
+2  A: 

Have you ever seen the Functional Java? It's a very interesting library that allows you programing like you would do in Scala. I Wrote about this libs. I confess it is better to use in a more flexible syntax (BGGA closures) like Scala.

Using Functional Java with a high-order function like map on a list we have:

final List<Integer> numbers = list(1, 2, 3, 4, 5);  

List<Integer> c = numbers.map(new F<Integer, Integer>() {  
                 public Integer f(Integer arg) {  
                   return arg * arg;  
                  }  
              });

Another useful lib is lambdaj that offers nice ways to play like in Functional (FP) Programming. Java has a limited syntax compared to FP languages. But you can still take some advantages of FP style, but you must be creative!

paulosuzart
Just to clarify: It looks like you might be saying Java 7 will have closures, but in fact this is not the case.
Michael Myers
mmyers, You'r right! But I do expect it becomes truth.
paulosuzart
Not in Java 7. Maybe in Java 8 (though maybe they'll call it Java 2.0 or something and confuse everyone).
Adam Jaskiewicz
A: 

the closest to a function argument is

an instance of a anonymous class with exactly one method.

    Runnable a = new Runnable(){

   run(){
    System.out.println("hello");
        }
    }

  myMethod(a);
Andreas Petersson