54

This is my code.

public class SubFunction {
    private String drawTribleX(){
        return trible("X");
    }
    private String trible(String t){
        return t + t + t;
    }
    public static void main(String[] args){
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }
}

Can I do something like this ?

public class SubFunction {
    private String drawTribleX(){
        // *** move trible(t) inside drawTribleX() ***
        private String trible(String t){
            return t + t + t;
        }
        return trible("X");
    }
    public static void main(String[] args){
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }
}

Thank you.

aioobe
  • 413,195
  • 112
  • 811
  • 826
diewland
  • 1,865
  • 5
  • 30
  • 41
  • 7
    If you had typed your example into an IDE its compiler would already have told you the answer. – Bombe Mar 22 '11 at 08:41
  • 1
    Possible duplicate of [Nested functions in Java](http://stackoverflow.com/questions/7367714/nested-functions-in-java) – Anderson Green Sep 08 '16 at 04:22
  • 12
    @Bombe, not really. An IDE could have determined if OP could do *exactly* that. If you read carefully you would have noticed that the question was "Can I do *something like* this?" – aioobe Nov 13 '16 at 15:22

5 Answers5

120

Update 2014-02-09:

JDK 8 introduced lambdas (anonymous function expressions) which allow you to solve it like this:

Function<String, String> trible = s -> s+s+s;
System.out.println(trible.apply("X"));           // prints XXX

(JDK 7 and below)

No, Java does not support "directly" nested methods. (Most functional languages do though, including some JVM languages such as Scala and Clojure!)

Just for reference though; You can define local classes (classes within methods) so this does compile

class SubFunction {
    private String drawTribleX(){

        // *** move trible(t) inside drawTribleX() ***
        class Trible {
            private String trible(String t){
                return t + t + t;
            }
        }

        return new Trible().trible("X");
    }
    public static void main(String[] args){
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }
}

Note though that there are some restrictions on local classes

3.11.2. Restrictions on Local Classes

Local classes are subject to the following restrictions:

  • A local class is visible only within the block that defines it; it can never be used outside that block.

  • Local classes cannot be declared public, protected, private, or static. These modifiers are for members of classes; they are not allowed with local variable declarations or local class declarations.

  • Like member classes, and for the same reasons, local classes cannot contain static fields, methods, or classes. The only exception is for constants that are declared both static and final.

  • Interfaces cannot be defined locally.

  • A local class, like a member class, cannot have the same name as any of its enclosing classes.

  • As noted earlier, a local class can use the local variables, method parameters, and even exception parameters that are in its scope, but only if those variables or parameters are declared final. This is because the lifetime of an instance of a local class can be much longer than the execution of the method in which the class is defined. For this reason, a local class must have a private internal copy of all local variables it uses (these copies are automatically generated by the compiler). The only way to ensure that the local variable and the private copy are always the same is to insist that the local variable is final.

So, as you can see, your first option (without nested methods) is preferable in these situations.

aioobe
  • 413,195
  • 112
  • 811
  • 826
  • 19
    Major +1 for keeping this answer up to date. – Paul Richter Feb 27 '14 at 15:37
  • Can the method `trible` inside the class `Trible` be `static`? This will avoid having to create an object `new Trible()` as you could just call the static method: `Trible.trible("X")`. On a related note, can the class `Trible` itself be `static`? Will that offer any advantage? – ADTC May 05 '14 at 07:36
  • 1
    No. It's in the second bullet under 3.11.2. – aioobe May 05 '14 at 07:51
9

Quite simply - no. You can't nest a method within another method.

If you really want to do this, you can define classes within methods (strangely, given the previous restriction) and so could wrap your methods within a class within the outer method.

However, this isn't very idiomatic, and the general practice seems to be to have a list of private methods (in the top level class), perhaps grouped according to purpose and with comment blocks demarcating the groups.


If you happen to find yourself using Scala, however, you can nest methods away to your heart's content...

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
2

you can try in this way as well which is anonymous inner class.

public class SubFunction {
    private String drawTribleX() {
        // *** move trible(t) inside drawTribleX() ***
        Trible t = new Trible() {
            public String trible(String t) {
                return t + t + t;
            }
        };
        return t.trible("X");
    }

    public static void main(String[] args) {
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }

    interface Trible {
        String trible(String t);
    }
}
GuruKulki
  • 25,776
  • 50
  • 140
  • 201
1

It is possible to write lambdas inside any method.

Using lambda for example to create a recursive method:

Expecting an object like

class Foo{
   Foo parent;
}

Interface for the lambda method expression

public interface Function<ARGUMENTTYPE, RETURNTYPE>{
    RETURNTYPE apply(ARGUMENTTYPE argument);
}

Recursive findRoot method to get the top level Foo.parent

private Foo findRoot(final Foo foo) {
    //Create a Lambda Function for recursive search.
    final Function<Foo, Foo> recursiveSearch = new Function<Foo, Foo>() {
        @Override
        public Foo apply(final Foo fee) {
            //is the parent null return null
            if (fee.parent == null) {
                return null;
            } else if (fee.parent.equals(fee)) {
                //safety check ;-)
                throw new IllegalStateException("Circular Dependencies of " + fee.toString());
            } else {
                Foo parentFoo = fee.parent;
                //check if parent has parent otherwise return parent in else block
                if (parentFoo != null && parentFoo.parent != null) {
                    return this.apply(parentFoo);
                } else {
                    return parentMarket;
                }
            }
        }
    };
    //get the root
    final Foo rootFoo = recursiveSearch.apply(foo);
    //Safety check 2 ;-)
    if (rootFoo != null && rootFoo.equals(foo)) {
        throw new IllegalStateException("Circular Dependencies of " + foo.toString)();
    }
    return rootFoo;
}
Pwnstar
  • 2,333
  • 2
  • 29
  • 52
1

You could use an anonymous class. Something like this;

class SubFunction {

    public static void main(String[] args) {
        SubFunction o = new SubFunction();
        System.out.println(o.drawTribleX());
    }

    private String drawTribleX() {
        MyTrible trible = new MyTrible() {
            @Override
            public String doTrible(String t) {
                return t + t + t;
            }
        };

        return trible.doTrible("X");
    }

    private interface MyTrible {
        public String doTrible(String t);
    }
}

If you wanted you could define different types of operations with the same interface, and pass these around as you like.

firefox1986
  • 1,602
  • 11
  • 9