Java 对空对象调用静态方法

Java 对空对象调用静态方法,java,null,Java,Null,我很想知道你如何解释我在这本书中发现的这个任务? 即使getFoo方法返回null,输出仍然是getingobjectjavaquick。我认为应该是NullPointerException public class Foo { static String name = " JavaQuiz"; static Foo getFoo() { System.out.print("Getting Object");

我很想知道你如何解释我在这本书中发现的这个任务? 即使
getFoo
方法返回
null
,输出仍然是
getingobjectjavaquick
。我认为应该是
NullPointerException

   public class Foo {

        static String name = " JavaQuiz";

        static Foo getFoo() {
            System.out.print("Getting Object");
            return null;
        }

        public static void main(String[] args) {
            System.out.println(getFoo().name);
        }

   }

访问静态方法或变量可以通过包含该静态方法/变量的类的null引用来完成

由于
name
是静态的,
getFoo().name
的结果与
Foo.name
或只是
name
,而不管
getFoo()
是否返回
null


但是,在访问静态方法/变量时最好使用类名,因为它清楚地表明您打算访问静态成员。

类的静态成员是
类的
级别成员,这意味着不需要对象来访问这些
静态成员`

jvm
classloader
加载类时,它会自动加载。所以在这个例子中

static String name = " JavaQuiz"; //load when class get loaded by JVM class loader.
在类
Foo
加载到
jvm
之后,这个
static
变量将存在于内存中

static Foo getFoo() {  //method is also a static Member automatically loaded at Class Loading.
            System.out.print("Getting Object");
            return null;
        }
这个静态方法
getFoo()
也同样适用

所以这里是
System.out.println(getFoo().name)。
这里有一个例子来简化我的答案

class StaticExample
{
    static String abc ="India";
    public static void main (String[] args) throws java.lang.Exception
    {
        StaticExample obj = null;
        System.out.println("Value is ==>" + obj.abc + StaticExample.abc + abc);
    }
}
输出:-

 Value is ==>IndiaIndiaIndia
 Value is ==>India
在这里,这行代码也将生成输出

     System.out.println(((Ideone)null).abc); // this will also print India.
输出:-

 Value is ==>IndiaIndiaIndia
 Value is ==>India
注意:-我认为关于
getFoo()
方法存在混淆,但如果
.name
造成歧义
name
是一个静态成员,因此它可以使用
className
或任何
null
引用进行访问。因此,这里您可以假设这种情况,即使用任何空引用访问此
name
变量

希望你能明白这一点。

反汇编
(javap-cfoo)
Foo.java文件的字节码揭示了隐藏的信息,即当
名称
静态的
时,为什么你看不到NullPointerException

对于上面的代码,当反汇编时,它产生以下输出

如果我们查看黄色框,我们会看到编译器标识我们正在尝试访问一个静态字段,因此它放置getstatic指令以获取字段
name
。因此,这实际上不会使用从
getFoo
方法返回的实例来获取
name
字段的值,因此不会引发NPE


如果我们删除
String name=“javaquick”前面的
static
关键字,它会产生以下反汇编代码

这里我们可以看到java编译器指示使用
getfield
指令,这将在实例上调用,即从
getFoo
方法返回。因此,如果
getFoo
方法返回
null
,这将引发NPE

因此,在这种情况下,java编译器在编译过程中发挥了神奇的作用,也就是说,如果代码正在调用静态字段,它将放置
getstatic
指令,而不会导致使用对象引用


我们可以找到有关指令集的更多信息。

先生,我知道这可能不是写评论的方式。但是,你的知识确实令人震惊。总是从你的答案中学习。:)