为什么方法中不允许使用静态本地类?

我一直在刷我的java,我对本地类(我最终从未使用过)有一些误解,我很清楚静态的概念,但不是本地类的情况。

1.为什么本地类不允许使用静态方法?

2.为什么方法中不允许使用静态本地类?

  1. 本地类中不允许使用静态方法:

在这里,我不明白。 对我来说,本地类与静态方法main相关联。 我只是不明白为什么不能这样做。 方法main通过Sequence类访问,然后因为sayGoodbye是静态的,所以应该通过它的类访问它。 但不是。

public class Sequence { public static void main(String... args) { class EnglishGoodbye { public static void sayGoodbye() { // this cannot be done System.out.println("Bye bye"); } } EnglishGoodbye.sayGoodbye(); } } 
  1. 方法中不允许使用静态本地类:

这是不可能做到的:它有点含糊不清但我认为这里的静态与非静态具有相同的含义,因为静态类与静态方法相关联。 我很困惑。

 public class Sequence { public static void main(String... args) { static class EnglishGoodbye { //static local classes not allowed public static void sayGoodbye() { System.out.println("Bye bye"); } } EnglishGoodbye.sayGoodbye(); } } 

编辑:我得到的第一个答案是来自oracle的引用:

本地类是非静态的,因为它们可以访问封闭块的实例成员。 因此,它们不能包含大多数类型的静态声明。

和我的回复:

但这并没有真正解释一切。 如果您有内部类,则无法访问非静态字段,但可以访问静态字段。 同样应该适用于本地类,因为没有静态变量,所以它没用。 但是在我的例子中,方法呢。

好吧,我制作了一个模式来更好地解释我如何看待事物。 虽然这可能完全是错误的,但我有点羞于表现出来。 在这个模式中,在可以访问静态本地类的场景中,我在顶部内存块中有一个本地类。 每当调用静态方法2时,它只会引用它。

在此处输入图像描述

Java中有两种类:顶级和嵌套。
嵌套类有两种:静态嵌套和内部。
还有两种特殊的内部类:本地类和匿名类。

根据定义 ,本地类和匿名类是内部类,即非静态类。

请参阅Java™教程 – 本地类与内部类相似 :

本地类是非静态的,因为它们可以访问封闭块的实例成员。 因此,它们不能包含大多数类型的静态声明。

但是,你已经看到了,所以让我引用JLS§14.3本地类声明 :

所有本地类都是内部类(第8.1.3节 )。


推理 (我的意见)

第一个例子有什么意义?

 public static void main(String... args) { class EnglishGoodbye { public static void sayGoodbye() { // this cannot be done System.out.println("Bye bye"); } } EnglishGoodbye.sayGoodbye(); } 

只需将该方法作为主类的private static

 public static void main(String... args) { sayGoodbye(); } public static void sayGoodbye() { System.out.println("Bye bye"); } 

哦,你想从方法中访问变量和参数吗?

 public static void main(String... args) { final String message = "Bye bye"; class EnglishGoodbye { public static void sayGoodbye() { // this cannot be done System.out.println(message); } } EnglishGoodbye.sayGoodbye(); } 

问题是static方法没有实例上下文,那么message实例是什么?

要指定实例,需要一个new EnglishGoodbye()语句,编译器会将隐藏的实例字段添加到EnglishGoodbye来表示message的值,这也是message必须(有效)最终的原因,因为它正在复制值变量。 请记住,与C不同,您不能通过指针引用变量。

 public static void main(String... args) { final String message = "Bye bye"; class EnglishGoodbye { public void sayGoodbye() { System.out.println(message); } } new EnglishGoodbye().sayGoodbye(); } 

第二个例子也是如此。 有什么意义?

 public static void main(String... args) { static class EnglishGoodbye { //static local classes not allowed public static void sayGoodbye() { System.out.println("Bye bye"); } } EnglishGoodbye.sayGoodbye(); } 

只需使类成为主类的private static

 public static void main(String... args) { EnglishGoodbye.sayGoodbye(); } private static class EnglishGoodbye { public static void sayGoodbye() { System.out.println("Bye bye"); } } 

与第一个示例相同的推理,如果您打算访问方法变量和参数。 该类需要一个实例,以了解要访问的变量/参数的哪个实例。


并不是说它与答案直接相关,但我做了这个,所以不妨保留它。

以下是Java类型系统作为层次结构(不要与inheritance/子类型混淆)

  • 类型 ( §4 )
    • 原始类型 ( §4.2 )
      • booleanbyteshortintlongcharfloatdouble
    • 参考类型 ( §4.3 )
      • null类型( §4.1 )
      • 输入变量 ( §4.4 ),
      • 数组类型 ( §10.1 )
      • 接口 ( §9.1 )
        • 注释类型 ( §9.6 )
        • 正常界面
          • 顶级界面 ( §7.6 )
          • 嵌套接口 ( §8.5 , §9.5 )
      • ( §8.1 )
        • 枚举类型 ( §8.9 )
        • 正常class级
          • 顶级课程 (第7.6节 )
          • 嵌套类 ( §8.5 , §9.5 )
            • 静态嵌套类
            • 内在阶级 ( §8.1.3 )
              • 本地class级 ( §14.3 )
              • 匿名课程 ( §15.9.5 )