Java 内部 class 使用静态方法
Java inner class with a static method
我知道这个问题有点简单,但我真的想知道为什么而不是去文档假设我有 class 这样的。
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;
}
}
}
两个静态方法都抛出一个错误,指出
修饰符'static'只允许在常量变量声明中使用
我知道文档指出
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).
但我的问题是调用简单值或 属性 与调用静态方法的区别是 public 还是私有?为什么可以调用 属性 而不是方法。
谢谢。
Non-static内部class有一些特别的东西。
static inner classes 没有。 top-level classes 没有。任何内部接口或枚举都没有。
那个特殊的东西是一个看不见的领域。
这个不可见字段的类型是Outer
,它是final
。它在其构造函数中被初始化为第一件事,并且,是的,non-static 内部 class 的每个构造函数都有一个魔法不可见参数,类型为 Outer
,用作此字段。
所以,当你写:
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
反编译工具看到这个隐藏的魔法;传入 -verbose
和 -private
,您将看到这些。这种魔法存在的原因是您可以从内部调用外部的实例方法,但是..您在什么实例上调用这些外部方法?在那个隐藏的实例上!
请注意,这个奇异的、看似怪异的代码:someOuter.new Inner()
实际上是合法的 java 代码。当从 Outer
中的 non-static 上下文中调用 new Inner()
时,this
实例作为不可见参数传递给该构造函数,但如果您不在那里,代码只是根本无法编译...除非您使用 outer.new Inner()
语法。
编译器会阻止您向 Inner
添加静态方法的原因是它被认为会导致一些混乱。基本上,您问题的答案是:"No good reason.. just... the spec says that a java compiler must not allow it, therefore, javac does not allow it".
请注意,实际上这些 non-static 内部 class 是令人困惑的东西。我强烈建议你自学 ALWAYS 使你的内在 classes static
除非你 真的 知道你是什么正在做。即使那样,也要三思。然后再三思。那么也许可以考虑制作一个 non-static inner class.
我知道这个问题有点简单,但我真的想知道为什么而不是去文档假设我有 class 这样的。
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;
}
}
}
两个静态方法都抛出一个错误,指出
修饰符'static'只允许在常量变量声明中使用
我知道文档指出
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).
但我的问题是调用简单值或 属性 与调用静态方法的区别是 public 还是私有?为什么可以调用 属性 而不是方法。
谢谢。
Non-static内部class有一些特别的东西。
static inner classes 没有。 top-level classes 没有。任何内部接口或枚举都没有。
那个特殊的东西是一个看不见的领域。
这个不可见字段的类型是Outer
,它是final
。它在其构造函数中被初始化为第一件事,并且,是的,non-static 内部 class 的每个构造函数都有一个魔法不可见参数,类型为 Outer
,用作此字段。
所以,当你写:
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
反编译工具看到这个隐藏的魔法;传入 -verbose
和 -private
,您将看到这些。这种魔法存在的原因是您可以从内部调用外部的实例方法,但是..您在什么实例上调用这些外部方法?在那个隐藏的实例上!
请注意,这个奇异的、看似怪异的代码:someOuter.new Inner()
实际上是合法的 java 代码。当从 Outer
中的 non-static 上下文中调用 new Inner()
时,this
实例作为不可见参数传递给该构造函数,但如果您不在那里,代码只是根本无法编译...除非您使用 outer.new Inner()
语法。
编译器会阻止您向 Inner
添加静态方法的原因是它被认为会导致一些混乱。基本上,您问题的答案是:"No good reason.. just... the spec says that a java compiler must not allow it, therefore, javac does not allow it".
请注意,实际上这些 non-static 内部 class 是令人困惑的东西。我强烈建议你自学 ALWAYS 使你的内在 classes static
除非你 真的 知道你是什么正在做。即使那样,也要三思。然后再三思。那么也许可以考虑制作一个 non-static inner class.