按类引用字段和按对象调用字段有什么区别?

我注意到有些时候用Java编写的代码我看过方法调用的字段:

System.out.println(object.field); 

按class级分类:

 System.out.println(Class.field); 

在我的教科书中,我没有看到任何关于这两种情况的语义是什么的明显区别,我担心,至少对于一个菜鸟来说,这将是一个微妙的观点。 我的直觉是类调用将用于静态字段? 多谢你们。 如此多的con’foo’sion。

可以在不创建类实例的情况下访问字段Class.field 。 这些是static字段,在类加载器加载类时会初始化这些字段。

只有在创建类的实例时才能访问其他字段即object.field 。 这些是在通过调用其构造函数创建类的对象时初始化的instance字段。

object.field应该是(见下面的注释)一个实例成员,而Class.field是一个静态成员。

注意:就像@radai所述并且我认为值得一提,您也可以通过对象实例访问静态成员,但这是一种非常糟糕的做法,这是非常误导的。

实例范围与类范围。

看一下这个:

 class Foobar { public final int x = 5; public static final int y = 6; } 

y是一个仅在编译时创建一次的变量。 它与类绑定,因此由其所有实例共享。 你可以用Foobar.y引用它。

 System.err.println(Foobar.y); 

另一方面, x是一个实例变量,你用new创建的每个Foobar都有一个副本。 你会像这样引用它:

 Foobar foobar = new Foobar(); System.err.println(foobar.x); 

但这不起作用:

 System.err.println(Foobar.x); 

按类重新放置字段要求字段是静态的。

按对象重新生成字段要求字段可以是静态字段或非静态字段。

我的直觉是类调用将用于静态字段

SomeClass.field只能在fieldstatic 。 在这种情况下,您也可以通过像someClassRef.field这样的引用来访问它,但无论如何这个代码将由编译器更改为ReferenceType.field 。 此外,它可能会导致一些误解(可能看起来您正在尝试使用非静态字段),因此最好通过其类使用静态字段。

如果field不是静态的,那么它必须属于某个实例,因此你必须通过引用someClassRef.field来调用它