所以,我是一个java noob,我刚刚遇到了一些让我困惑的事情
public class Main
{
public static void main(String[] args)
{
Foo foo = new Foo("Foo");
}
}
class Foo
{
public Foo(String A)
{
System.out.println(A);
}
}
我注意到Foo类不一定是静态的。为什么?而
如果我做这个
public class Main
{
public static void main(String[] args)
{
Foo foo = new Foo("Foo");
}
static class Foo
{
public Foo(String A)
{
System.out.println(A);
}
}
}
那么它必须是静态的。为什么有区别?静态意味着它与实例无关,因此静态方法中使用的每一个东西都必须与实例无关(?)对于Foo,我在静态方法中创建了实例,所以Foo不需要是静态的。但是,有课在里面有什么区别呢?我以为我已经有了静态的概念。但显然我缺乏很多概念。
JLS-8.1.3对此进行了说明。内部类和封装实例(部分)表示
内部类是未显式或隐式声明
static
的嵌套类。内部类可以是非
static
成员类(§8.5)、本地类(§14.3)或匿名类(§15.9.5)。接口的成员类是隐式static
(§9.5),因此永远不会被视为内部类。
因此,静态类不是内部类,内部类需要封闭类的实例;像
public class Main {
public static void main(String[] args)
{
Foo foo = new Main().new Foo("Foo");
}
class Foo
{
public Foo(String A)
{
System.out.println(A);
}
}
}
在第二个代码片段中,Foo
嵌套在Main
中。嵌套类可以是内部类,也可以是静态类。如果它们是内部类(非静态),则内部类的每个实例都必须与封闭类的一个实例相关联。
因此,如果在第二个代码段中从Foo
类中删除static
关键字,则必须使用对其进行实例化
Foo foo = new Main().new Foo("Foo");
当嵌套类是静态的时,它不需要封闭类的实例,并且可以使用实例化它
Foo foo = new Foo("Foo");
另一方面,在您的第一个代码段中,Foo
没有嵌套在Main
中,因此您不需要Main
的实例来实例化它。而且它不能是静态的,因为顶级类不能是静态。
我以为我已经有了静态的概念。但显然我缺乏很多概念。
当应用于嵌套类时,static
关键字与应用于方法和变量时具有不同的含义。您应该阅读有关嵌套类的内容。
在上面的例子中,在同一个文件中有两个独立的类。main
可以引用Foo
,因为它只是另一个类。
在底部的示例中,您有一个静态嵌套类。它还可以独立实例化。如果去掉Foo
上的static
关键字,则会有一个内部类,绑定到Main
的特定实例,但当运行静态main
方法时,没有可引用的Main
的特定实例。
此参考资料可能有助于:https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html
在java中,我们不能使顶级类成为静态的。只有嵌套类可以是静态的。因此,对于第一个场景,您将无法将Foo类设置为静态。对于第二个场景,非静态嵌套类(内部类)可以访问封闭类的其他成员,即使它们被声明为私有。静态嵌套类不能访问封闭类的其他成员。
如果你需要一个类的非静态声明、字段、方法等,你需要从这个类创建一个实例。
但是要访问静态字段,方法不需要创建实例。
现在看看你的例子;
1.Main和Foo是不同的类,因此您可以在任何地方从Foo创建实例。
public class Main {
public static void main(String[] args) {
Foo foo = new Foo("Foo");
}
}
class Foo {
public Foo(String A) {
System.out.println(A);
}
}
2.Foo是一个内部类,如果没有创建Main的实例,则Foo类永远无法访问。因此,如果你创建了一个Main实例,你也可以创建Foo。但在不创建Main实例的情况下,只访问Foo就是将Foo类定义为静态
public class Main {
public static void main(String[] args) {
Foo foo = new Foo("Foo");
}
static class Foo {
public Foo(String A) {
System.out.println(A);
}
}
}