Java 方法局部内部类程序

Java 方法局部内部类程序,java,inner-classes,Java,Inner Classes,我只是在学习Java概念。 有人能告诉我为什么我不能运行这个程序吗 package innerClasses; public class Test { int i=10; static int j=20; public void m1() { int k=30; final int m=40; class Inner { public void m2() { Sys

我只是在学习Java概念。 有人能告诉我为什么我不能运行这个程序吗

package innerClasses;

public class Test {
    int i=10;
    static int j=20;
    public void m1() {
        int k=30;
        final int m=40;

        class Inner {
            public void m2() {
                System.out.println(i);
            }
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        Test.Inner in = t.new Inner();
        t.m1();
    }

}

有人能告诉我为什么我不能运行这个程序吗?

最基本的原因是因为范围。为了做

package innerClasses;

public class Test {
    int i=10;
    static int j=20;
    public void m1() {
        int k=30;
        final int m=40;

        class Inner {
            public void m2() {
                System.out.println(i);
            }
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        Test.Inner in = t.new Inner();
        t.m1();
    }

}
Test.Inner in = t.new Inner();
必须在Test中定义Inner,但它是在m1范围中定义的。

类Inner是在方法m1中声明的,这使得它在该方法之外不可用

您的代码必须如下所示才能运行,尽管它不会打印任何内容

public class Test {

    int i=10;
    static int j=20;

    public void m1() {
        int k=30;
        final int m=40;
    }

    class Inner {
        public void m2() {
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        Test.Inner in = t.new Inner();
        t.m1();
    }

}
替换t.m1;单位:平方米;将输出10

编辑

如果您必须在方法内部创建内部类,请将其设置为

public class Test {

    int i=10;
    static int j=20;

    public void m1() {

        int k=30;
        final int m=40;

        class Inner {
            public void m2() {
                System.out.println(i);
            }
        }

        // this is what makes it run
        Inner myInner = new Inner();
        myInner.m2();
    }


    public static void main(String[] args) {
        Test t = new Test();
        t.m1();
    }

}
编译并运行


我想这不是一个好办法…

方法内部类仅对该方法可见,因此您不能在任何其他位置使用它


要使用这个类,您必须在方法之外声明它。

您不能编译它,因为内部类的作用域是m1方法。 如果希望能够创建内部类的实例,可以直接在测试中定义它:

public class Test {
    int i=10;
    static int j=20;

    public void m1() {
        int k=30;
        final int m=40;
    }

    // On the Test class level 
    class Inner {
        public void m2() {
            System.out.println(i);
        }
    }

    public static void main(String[] args) {
        Test t = new Test();
        Test.Inner in = t.new Inner();
        t.m1();
        in.m2(); // prints 10
    }
}
Java提供的另一个特性是使用匿名类。它可以通过实现某些接口来创建:

// Define an interface to be able to implement it inside the method
interface Inner {
    void m2();
}

public class Test {
    int i=10;
    static int j=20;

    public void m1() {
        int k=30;
        final int m=40;

        // Implement interface and call method on it
        // Functional style: 
        ((Inner) () -> System.out.println(i)).m2();

        // Legacy style:
        new Inner() {
            @Override
            public void m2() {
                System.out.println(i);
            }
        }.m2();

    }

    public static void main(String[] args) {
        Test t = new Test();
        t.m1(); // prints 10 twice
    }
}
或者扩展某个类:

// A class we going to extend
class Inner {
    void m2() {
        System.out.println(11);
    }
}

public class Test {
    int i=10;
    static int j=20;

    public void m1() {
        int k=30;
        final int m=40;

        // Extend inner class and call method on it
        new Inner() {
            void m2() {
                System.out.println(i);
            }
        }.m2();

    }

    public static void main(String[] args) {
        Test t = new Test();
        t.m1(); // prints 10, not 11
    }
}
因此,您的最佳方式取决于您希望最终获得的代码设计。

您的类内部是JLS所称的

委员会:

由§14.2块直接封闭的本地类声明的范围是直接封闭块的其余部分,包括其自身的类声明

立即由开关块语句组§14.11封闭的本地类声明的范围是立即封闭的开关块语句组的其余部分,包括其自身的类声明

在本例中,它是在块中声明的,块是方法的主体。因此,类可见的范围是该方法体的其余部分


由于类型Inner在main中不可见,因此不能在那里使用它。不过,您可以创建它的实例并在m1中使用它们。

编译时错误的最基本原因是作用域。 根据您的代码,类内部是在方法m1内定义的。该类称为局部类/方法局部类,因此,如果您观察方法变量的范围,它仅在声明的方法内,并且我们无法访问该方法之外的任何方法变量,这就是原因,类内部的范围仅限于m1方法 因此,如果您想实例化类内部并调用其方法,那么您必须在代码中的m1方法中执行,您正在尝试在方法m1之外创建类内部对象,这是不可能的,因此代码将是

public class Test {
int i = 10;
    static int j = 20;
    public void m1() {
        int k = 30;
        final int m = 40;
        class Inner {
            public void m2() {
                System.out.println(i);
            }
        }
        Inner in = new Inner();
        in.m2();
    }
    public static void main(String[] args) {
        Test t = new Test();
        t.m1();
    }
}
更多信息,当方法中需要任何重复的功能时,可以使用本地类,因为java中不允许使用嵌套方法,因此我们可以创建内部类,如果我们不想创建类级方法,则可以创建非内部类

class Outer {
    public void cal() { 
        class Inner {
            public void sum(int x, int y) {
                System.out.println("sum : "+(x+y));
            }
        }
        Inner i= new Inner();
        i.sum(10, 20); //sum is repeatdly needed in between code
        i.sum(100, 200);
        i.sum(1000, 2000);
        i.sum(10000, 20000);
    }
}
public class TestClass {
    public static void main(String[] args) {
        new Outer().cal();
    }
}

你为什么不告诉我们?你收到错误信息了吗?它是否在编译/运行时出现?它说了什么?你不能在一个方法中声明一个类,更不用说假设它是一个有效的内部类。编译时错误在这一行说Multiple marker,Test。内部不能解析为一个类型。原因在我的第二条评论中。我建议你仔细阅读。问题是您试图创建一个局部类,并试图将其用作内部类:但是根据方法局部内部类的概念,我们可以在方法中声明一个类。问题仍然存在。您的主声明试图访问嵌套类,但您正在定义一个方法本地类。如果您的目的是实际访问方法本地类,那么你只能在m1的上下文中进行。实际上,我使用的是方法局部内部类的概念,根据这个概念,我必须在m1中定义内部类。@AnkitJain请查看我的编辑并回答我为什么要在另一个类的方法中声明一个类的问题?