专栏首页浩CodingJava中静态方法不能调用非静态方法的原因

Java中静态方法不能调用非静态方法的原因

如图,是Java中静态代码和实例对象互相调用的规则,我们接下来就讲讲为什么在Java中静态方法不可以调用非静态代码呢。

静态方法是属于类的,即静态方法是随着类的加载而加载的,在加载类时,程序就会为静态方法分配内存,而非静态方法是属于对象的,对象是在类加载之后创建的,也就是说静态方法先于对象存在,当你创建一个对象时,程序为其在堆中分配内存,一般是通过this指针来指向该对象。静态方法不依赖于对象的调用,它是通过‘类名.静态方法名’这样的方式来调用的。而对于非静态方法,在对象创建的时候程序才会为其分配内存,然后通过类的对象去访问非静态方法。因此在对象未存在时非静态方法也不存在,静态方法自然不能调用一个不存在的方法。

在做一个笔试的时候遇到的问题:有下面这样的程序:

public class TestStatic {
  private static void Print() {
    System.out.println("Print()");
  }
  public static void main(String[] args) {
    ((TestStatic) null).Print();
  }
}

运行结果是 Print() :

当时看到这道题的时候真的是万脸懵逼,为什么类名那里还要加一个null,为什么不是直接Test.Print(),还以为这样写会报错,然而并不是。经过查资料和某人的帮助,终于明白啦。

(1)首先,我们可以试一下去掉static,这里不会编译错误,但是运行时会抛出空指针异常,原因是什么呢,原因就是类似于上面说的静态方法不能调用非静态方法的原因了。我们很容易被null转移了视线,这里与null的关系不大(这是因为是静态方法,null没有影响),null是为了告诉我们这里的引用没有指向任何地方或者说还未初始化,也就是说对象未创建,从上面对象的创建过程可以知道,如果对象还未创建,则不会有this指针的引用,因此会报空指针异常。

(2)这里用null的话(即(Test)null)是将Test引用强制转换为Test对象,这样也可以调用静态方法,其实不需要null,也是可以调用静态方法的,即Test.Print()。

另外补充一下我觉得很有必要知道的null的知识:

(1)null可以被强制转换为任何引用类型。

(2)任何含有null值的包装类在自动拆箱成基本数据类型时都会抛出一个空指针异常。

(3)不能用一个值为null的引用类型变量来调用非静态方法,这样会抛出空指针异常,但是静态方法可以被一个值为null的引用类型变量调用而不会抛出空指针异常。这和对象的创建和静态方法以及非静态方法之间的关系有关。也就是上面说的那些。

本文分享自微信公众号 - 浩Coding(gh_c4a2e63d2ca7),作者:浩

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-15

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 类中的静态/非静态方法

     C#的类中可以包含两种方法:静态方法和非静态方法。   使用了static 修饰符的方法为静态方法,反之荝是非静态方法。   静态方琺是①種 特殊的成園方琺,...

    DougWang
  • laravel框架模型中非静态方法也能静态调用的原理分析

    本文实例讲述了laravel框架模型中非静态方法也能静态调用的原理.分享给大家供大家参考,具体如下:

    砸漏
  • 详解Java中静态方法

    定义: 在类中使用static修饰的静态方法会随着类的定义而被分配和装载入内存中;而非静态方法属于对象的具体实例,只有在类的对象创建时在对象的内存中才有这个方法...

    用户7886150
  • Java中的静态方法不能被子类重写

    结论:Java中的静态方法不能被子类重写,实际上,子类的静态方法隐藏了父类的静态方法,因此父类的子类的静态方法同时存在,只不过父类通过类名(或对象名)调用的是父...

    用户7886150
  • JNI--非静态native方法使用及c/c++调用Java变量

    aruba
  • java的静态工厂方法

    在 Java 中,获得一个类实例最简单的方法就是使用 new 关键字,通过构造函数来实现对象的创建。 就像这样:

    码农王同学
  • php面向对象中static静态属性和静态方法的调用

    这篇文章主要介绍了php面向对象中static静态属性和静态方法的调用,实例分析了static静态属性和静态方法的原理与调用技巧,需要的朋友可以参考下 本文实例...

    joshua317
  • Android NDK编程(五)--- C/C++调用Java不同类中的静态方法

    上一篇我们介绍了《Android NDK编程(四)--- C/C++调用Java中的方法》,主要是C/C++中调用Java的方法,这一篇我们针对上一篇的内容再延...

    Vaccae
  • Java 静态方法和实例方法有何不同

    ●在外部调用静态方法时,可以使用"类名.方法名"的方式,也可以使用"对象名.方法名"的方式。而实例方法只有后面这种方式。也就是说,调用静态方法可以无需创建对象。

    赵哥窟
  • 【小家java】静态类、静态方法、内部类、匿名内部类、非静态类的一些实践

    静态内部类的作用:只是为了降低包的深度,方便类的使用,实现高内聚。静态内部类适用于不依赖于外部类,不用使用外在类的非静态属性和方法,只是为了方便管理类结构而定义...

    YourBatman
  • javascript当中静态方法和prototype用法

    6)静态方法和prototype(难) 例 3.6.1 <head> <meta http-equiv="content-type" content="...

    马克java社区
  • java静态方法和实例方法的区别

    调用静态方法或说类方法时,可以使用类名做前缀,也可以使用某一个具体的对象名;通常使用类名。

    马克java社区
  • c#中的静态本地方法

    在 C# 8 中微软增加了静态本地方法,这种类型的方法无法获取和修改任何本地变量和实例成员。下面我们来看一下这种方法的具体用法。 首先我们来看一下普通的方法:

    喵叔
  • 关于公共类中常见的静态方法需要调用spring注入的非静态变量的解决方案

    当你编写一个需要调用mybatis的dao层的类时,会先通过spring依赖注入该变量,但是由于你需要用到该变量在静态方法中,所以无法使用,此时你将该变量改为静...

    动力节点Java培训
  • python中类的静态方法和类的类方法

    类的静态方法,不需要self这类参数,因为类的静态方法,不需要进行实例化,就可以进行调用。

    刘金玉编程
  • Python中类的静态方法、类方法及实例方法

    经过测试可以发现 实例属性需要通过实例对象来访问,类属性通过类来访问,但在测验中 stu1.school 实例对象也能访问类属性,为什么呢?

    忆想不到的晖
  • Python中类的静态方法、类方法及实例方法

    经过测试可以发现 实例属性需要通过实例对象来访问,类属性通过类来访问,但在测验中 stu1.school 实例对象也能访问类属性,为什么呢?

    ZackSock
  • Java内部类——静态和非静态内部类、匿名内部类、方法内部类

    概念讲义转载自https://www.sxt.cn/Java_jQuery_in_action/five-inner-class.html

    逆回十六夜
  • PHP类的静态(static)方法和静态(static)变量使用介绍

    2. 直接调用类方法/变量:class::attribute/function,无论是静态/非静态都可以。但是有前提条件:

    用户7657330

扫码关注云+社区

领取腾讯云代金券