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

发布于 2024-10-25 07:13:33 字数 773 浏览 2 评论 0原文

这是我的代码。

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

谢谢。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏雨凉 2024-11-01 07:13:33

更新 2014-02-09:

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

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

(JDK 7 及更低版本) strong>

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

注意,尽管有一些本地类的限制

3.11.2。 本地课程的限制

本地课程受到以下限制:

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

  • 本地类不能声明为 public、protected、private 或 static。这些修饰符适用于类的成员;它们不允许与局部变量声明或局部类声明一起使用。

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

  • 接口无法在本地定义。

  • 本地类与成员类一样,不能与其任何封闭类同名。

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

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

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.

纵性 2024-11-01 07:13:33

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

如果您真的想要这样做,您可以在方法中定义(奇怪的是,考虑到前面的限制),因此可以将您的方法包装在外部方法内的类中。

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


然而,如果您碰巧发现自己使用 Scala,您可以随心所欲地嵌套方法......

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...

岁月蹉跎了容颜 2024-11-01 07:13:33

您也可以尝试这种方式,即匿名内部类。

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

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);
    }
}
靖瑶 2024-11-01 07:13:33

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

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

如果您愿意,您可以使用相同的接口定义不同类型的操作,并根据需要传递这些操作。

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.

゛时过境迁 2024-11-01 07:13:33

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

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

像 Interface 这样的对象

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

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文