2011-03-22 72 views
39

这是我的代码。Java是否支持inner/local/sub方法?

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

谢谢。

+4

如果你已经将你的例子输入到IDE中,它的编译器就会告诉你答案。 – Bombe 2011-03-22 08:41:54

+0

[Java中的嵌套函数]可能的重复(http://stackoverflow.com/questions/7367714/nested-functions-in-java) – 2016-09-08 04:22:16

+4

@Bombe,不是真的。一个IDE本来可以确定OP是否可以完全做到这一点。如果你仔细阅读,你会注意到问题是“我能做些什么*这样的事吗?” – aioobe 2016-11-13 15:22:21

回答

93

更新2014年2月9日:

JDK 8层推出的lambda(匿名函数表达式),它允许你解决这样的:

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。这些修饰符适用于类的成员;他们不允许使用局部变量声明或局部类声明。

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

  • 无法在本地定义接口。

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

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

所以,你可以看到,你的第一个选项(没有嵌套的方法)是在这些情况下,最好。

+11

保持此答案更新的主要+1。 – 2014-02-27 15:37:04

+0

“Trible”类内的'trible'方法可以是'static'吗?这样可以避免创建一个新的Trible()对象,因为您只需调用静态方法:Trible.trible(“X”)'。在相关的说明中,“Trible”类本身可以是“静态”吗?这会提供什么优势? – ADTC 2014-05-05 07:36:36

+1

不是,它位于3.11.2下的第二个项目符号中。 – aioobe 2014-05-05 07:51:31

6

很简单 - 没有。您不能在另一种方法中嵌套方法。

如果你真的要做到这一点,你可以定义方法中(奇怪的是,鉴于以前的限制),因此可以在外部方法中的类内包装你的方法。

但是,这并不是非常习惯用法,一般的做法似乎是拥有一个私有方法列表(在顶级类中),也许根据目的和评论块划分组来划分组。


如果你碰巧发现自己使用Scala的,但是,你可以嵌套方式离开你的心脏的内容...

1

你可以用这种方式尝试以及它是匿名内部类。

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

如果你想你可以定义不同类型的操作具有相同的接口,并为你喜欢周围传递这些。