Java是否支持内部/本地/子方法?

时间:2011-03-22 08:35:20

标签: java methods

这是我的代码。

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());
    }
}

我可以这样做吗?

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());
    }
}

谢谢。

5 个答案:

答案 0 :(得分:109)

更新2014-02-09:

JDK 8 引入了lambdas(匿名函数表达式),允许您像这样解决它:

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

(JDK 7及以下)

不,Java不支持“直接”嵌套方法。 (大多数函数式语言都可以,包括一些JVM语言,如Scala和Clojure!)

仅供参考;你可以定义本地类(方法中的类),这样 编译

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());
    }
}

请注意,有一些restrictions on local classes

  

3.11.2。 对本地课程的限制

     

本地课程受以下限制:

     
      
  • 本地类仅在定义它的块中可见;它永远不能在那个街区之外使用。

  •   
  • 无法将本地类声明为public,protected,private或static。这些修饰符适用于类的成员;它们不允许使用局部变量声明或本地类声明。

  •   
  • 与成员类一样,出于同样的原因,本地类不能包含静态字段,方法或类。唯一的例外是声明为静态和最终的常量。

  •   
  • 无法在本地定义接口。

  •   
  • 本地类(如成员类)不能与其任何封闭类具有相同的名称。

  •   
  • 如前所述,本地类可以使用局部变量,方法参数甚至是其范围内的异常参数,但前提是这些变量或参数是最终的。这是因为本地类实例的生命周期可能比定义类的方法的执行时间长得多。因此,本地类必须具有它使用的所有局部变量的私有内部副本(这些副本由编译器自动生成)。确保局部变量和私有副本始终相同的唯一方法是坚持局部变量是最终的。

  •   

因此,正如您所看到的,在这些情况下,您的第一个选项(没有嵌套方法)更可取。

答案 1 :(得分:8)

很简单 - 不。您不能将方法嵌套在另一个方法中。

如果真的想要这样做,你可以在方法中定义 classes (奇怪的是,考虑到之前的限制),所以可以将你的方法包装在一个类中外部方法。

然而,这不是非常惯用的,通常的做法似乎是拥有一个私有方法列表(在顶级类中),可能根据目的进行分组,并使用注释块划分组。


但是,如果您碰巧发现自己正在使用Scala,那么您可以将方法嵌入到您内心的内容中......

答案 2 :(得分:2)

你也可以尝试这种匿名的内部类。

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);
    }
}

答案 3 :(得分:0)

您可以使用匿名类。像这样的东西;

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);
    }
}

如果您需要,可以使用相同的界面定义不同类型的操作,并根据需要传递它们。

答案 4 :(得分:0)

可以在任何方法中编写lambda。

例如,使用lambda创建一个递归方法:

期望像

这样的对象
class Foo{
   Foo parent;
}

lambda方法表达式的接口

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

递归findRoot方法获得顶级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;
}