Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested functions in Java

Are there any extensions for the Java programming language that make it possible to create nested functions?

There are many situations where I need to create methods that are only used once in the context of another method or for-loop. I've been unable to accomplish this in Java so far, even though it can be done easily in JavaScript.

For example, this can't be done in standard Java:

for(int i = 1; i < 100; i++){     times(2); // Multiply i by 2 and print i     times(i); // Square i and then print the result      public void times(int num){          i *= num;         System.out.println(i);     } } 
like image 931
Anderson Green Avatar asked Sep 09 '11 21:09

Anderson Green


People also ask

Can you have nested functions in Java?

Java does not support “directly” nested methods. Many functional programming languages support method within method. But you can achieve nested method functionality in Java 7 or older version by define local classes, class within method so this does compile.

What do you mean by nested function?

In computer programming, a nested function (or nested procedure or subroutine) is a function which is defined within another function, the enclosing function.

Can you write a function within a function in Java?

You cannot (and in Java they are called methods).

How do you call a function inside another method in Java?

Example: public class CallingMethodsInSameClass { // Method definition performing a Call to another Method public static void main(String[] args) { Method1(); // Method being called. Method2(); // Method being called. } // Method definition to call in another Method public static void Method1() { System.


2 Answers

Java 8 introduces lambdas.

java.util.function.BiConsumer<Integer, Integer> times = (i, num) -> {     i *= num;     System.out.println(i); }; for (int i = 1; i < 100; i++) {     times.accept(i, 2); //multiply i by 2 and print i     times.accept(i, i); //square i and then print the result } 

The () -> syntax works on any interface that defines exactly one method. So you can use it with Runnable but it doesn't work with List.

BiConsumer is one of many functional interfaces provided by java.util.function.

It's worth noting that under the hood, this defines an anonymous class and instantiates it. times is a reference to the instance.

like image 77
Neal Ehardt Avatar answered Sep 22 '22 11:09

Neal Ehardt


The answer below is talking about the closest you can get to having nested functions in Java before Java 8. It's not necessarily the way I'd handle the same tasks which might be handled with nested functions in JavaScript. Often a private helper method will do just as well - possibly even a private helper type, which you create an instance of within the method, but which is available to all methods.

In Java 8 of course, there are lambda expressions which are a much simpler solution.


The closest you can easily come is with an anonymous inner class. That's as close as Java comes to closures at the moment, although hopefully there'll be more support in Java 8.

Anonymous inner classes have various limitations - they're obviously rather wordy compared with your JavaScript example (or anything using lambdas) and their access to the enclosing environment is limited to final variables.

So to (horribly) pervert your example:

interface Foo {     void bar(int x); }  public class Test {     public static void main(String[] args) {         // Hack to give us a mutable variable we can         // change from the closure.         final int[] mutableWrapper = { 0 };          Foo times = new Foo() {             @Override public void bar(int num) {                 mutableWrapper[0] *= num;                 System.out.println(mutableWrapper[0]);             }         };          for (int i = 1; i < 100; i++) {             mutableWrapper[0] = i;             times.bar(2);             i = mutableWrapper[0];              times.bar(i);             i = mutableWrapper[0];         }     } } 

Output:

2 4 10 100 

Is that the output you get from the JavaScript code?

like image 35
Jon Skeet Avatar answered Sep 25 '22 11:09

Jon Skeet