当前位置: 首页 > 知识库问答 >
问题:

具有静态方法的Java内部类

宇文鸣
2023-03-14

我知道这个问题有点简单,但我真的想知道为什么不去留档,假设我有这样的课。

public class OuterClass{
public static void main(String[] args)throws Exception{
    System.out.println(OuterClass.InnerClass.yearOfBorn);//works ok
    System.out.println(OuterClass.InnerClass.returnYearOfBorn());//not works
    System.out.println(OuterClass.InnerClass.returnYearOfBornAsPublic());//not works
}    
private final class InnerClass{
    private static final int yearOfBorn=13;
    private static int returnYearOfBorn(){
        return yearOfBorn;
    }        
    public static int returnYearOfBornAsPublic(){
        return yearOfBorn;
    }            
}

}

两个静态方法都抛出一个错误,指出

修饰符“静态”仅允许在常量变量声明中使用

我知道医生说

这在Java语言规范部分§8.1.3中有描述

8.1.3内部类和封闭实例

An inner class is a nested class that is not explicitly or implicitly declared static. Inner classes may not declare static initializers (§8.7) or member interfaces. Inner classes may not declare static members, unless they are compile-time constant fields (§15.28).

但我的问题是,调用简单值或属性与调用静态方法(无论是公共方法还是私有方法)有什么区别?。为什么可以调用属性,但不能调用方法。

谢谢

共有1个答案

仲孙兴旺
2023-03-14

静态内部类没有它。顶级类没有它。任何内部接口或枚举都没有它。

那个特殊的东西是一个看不见的领域。

此不可见字段的类型为“外部”(Outer),它是“最终”(final)。它被初始化为其构造函数中的第一件事,是的,非静态内部类的每个构造函数都有一个类型为“外部”的神奇的不可见参数作为此字段。

所以,当你写:

public class Outer {
    public class Inner {
    }
}

编译器将编译此代码,就好像您实际上编写了:

public class Outer {
    public static class Inner {
        private final Outer I_AM_MAGIC;

        public Inner(Outer outer) {
            this.I_AM_MAGIC = outer;
        }
    }
}

您可以使用javap反编译工具看到这种隐藏的魔法;传入-verose-Private,您会看到这些。这种魔法存在的原因是您可以从内部调用外部的实例方法,但是...你在哪个实例上调用这些外部方法?在那个隐藏的实例上!

请注意,这段奇怪的代码:someOuter。new internal()实际上是合法的java代码。当在外部的非静态上下文中调用新的内部时,这个实例将作为不可见的参数传递给该构造函数,但是如果你不在那里,代码根本不会编译。。。除非您使用外部。新建内部()语法。

编译器将阻止您向内部添加静态方法的原因是,它被认为会导致一些混淆。基本上,您的问题的答案是:“没有好的理由……只是……规范说java编译器不允许它,因此javac不允许它”。

请注意,实际上这些非静态内部类是令人困惑的事情。我强烈建议您自学始终使您的内部类静态,除非您真的知道自己在做什么。即便如此,三思。然后再三思。然后也许可以考虑制作一个非静态的内部类。

 类似资料:
  • 静态内部类是指使用 static 修饰的内部类。示例代码如下: 上述示例中的 Inner 类就是静态内部类。静态内部类有如下特点。 1) 在创建静态内部类的实例时,不需要创建外部类的实例。 2) 静态内部类中可以定义静态成员和实例成员。外部类以外的其他类需要通过完整的类名访问静态内部类中的静态成员,如果要访问静态内部类中的实例成员,则需要通过静态内部类的实例。 3) 静态内部类可以直接访问外部类的

  • 问题内容: 我知道创建一个非静态内部类对象需要一个外部类对象,而创建的非静态内部类对象会自动具有对该外部类对象的隐藏引用。但是为什么非静态内部类不能具有静态成员呢?Java设计人员只需要禁止在内部类的静态方法内访问非静态外部类字段,这样做会更有意义,不是吗? 如果在内部类中具有静态成员没有意义,那么为什么内部类可以通过继承具有静态成员的类来继承静态成员? 我也读了这篇文章。如前所述: 内部类可以继

  • 问题内容: 我了解到,Java文件中唯一的公共类也必须具有main方法。但是,下面您可以看到内部类内部的main方法呢?关于源文件中主要方法定义的规则是什么? 问题答案: 如果要使用Java(Java启动器:java test.MyClass)启动类,则该类必须具有带有众所周知签名的main方法。 您可以在任意位置使用具有相同签名的main方法。但是不要期望启动器会找到它。 PS语言的名称是Jav

  • 问题内容: 我有以下代码: 到目前为止,代码还不错,但是我无法像显示的那样在main方法中实例化 我该怎么做?我不想使我的课堂静止。 问题答案: 你还必须参考其他外部类。 如果内在是静态的,那将是

  • 问题内容: 我有点困惑。我已经按照google / android网站上的教程设置了一个,但出现以下错误: 当然,我确实有一个嵌套的静态类,但这是android / google定义它的方式。 为什么会出现此错误?我听说它最好用于嵌套类,这样您就不会浪费引用,但是最新版本的android studio抱怨 有任何想法吗? 问题答案: 直接回答您的问题: 内部类不能具有静态声明 完全是真的。这不是错

  • 我试图实现的是重写此方法: 公共布尔onKeyPreIme(int-keyCode,KeyEvent事件) 该方法位于SearchView中。搜索自动完成类http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.0_r1/android/support/v7/widget/Se