面试题--从JVM角度谈谈staitc为什么不能调用实例方法

本文详细介绍了Java虚拟机(JVM)的内存结构,包括堆、栈和方法区,以及静态变量和实例变量的存储位置。通过分析Person类的例子,阐述了静态方法和非静态方法的调用区别。静态方法由于没有this指针,无法调用非静态方法,因为非静态方法需要对象引用。此外,还讨论了static关键字的特性以及使用时的注意事项。
摘要由CSDN通过智能技术生成

从JVM角度谈谈staitc为什么不能调用实例方法

首先要了解一下Java的内存结构:
在这里插入图片描述
静态变量存放在方法区中,并且是被所有线程所共享的。Java堆存放的是我们创建的一个个实例变量。

堆区

  • 存储的全部是对象,每个对象都包含一个与之对应的class的信息(class的目的是得到操作指令)。
  • JVM只有一个堆区被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身。

栈区

  • 每个线程包含一个栈区,栈中只保存基本数据类型的对象和自定义对象的的引用,对象本身都存放在堆区中。
  • 每个栈中的数据都是私有的,其他栈不能访问。
  • 栈分为三个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)

方法区

  • 又叫静态区,跟堆一样,被所有的线程共享。方法区中包含所有的class和static变量。
  • 方法区中包含的都是在整个程序中永远唯一的元素,如class、static变量。

代码分析

自定义一个Person类:
在这里插入图片描述
内存:
在这里插入图片描述
我们的方法在调用的时候是从方法区中调用的,但是堆内存不一样,堆内存中的成员变量lastname是随着对象的产生而产生的,随着对象的消失而消失的。静态变量是所有线程共享的,所以不会消失。

static关键字

特点

  • static是一个修饰符,用于修饰成员(成员变量,成员函数),static修饰的成员变量称之为静态变量或类变量
  • static修饰的成员被所有的对象共享。
  • static优先于对象存在,因为static的成员随着类的加载就已经存在了
  • static修饰的成员多了一种调用方式,可以直接被类名所调用。
  • static修饰的数据是共享数据,对象中存储的是特有的数据。

成员变量和静态变量的区别

  • 生命周期不同
    成员变量随着对象的创建而存在随着对象的回收而释放。
    静态变量随着类的加载而存在随着类的消失而消失。
  • 调用方式不同
    成员变量只能被对象调用。
    静态变量可以被对象调用,也可以用类名调用。
  • 别名不同
    成员变量也称为实例变量。
    静态变量称为类变量。
  • 数据存储位置不同
    成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
    静态变量存储在方法区的静态区,所以也叫做对象的共享数据。

静态使用的注意事项

  • 静态方法只能访问静态成员,非静态既可以访问静态又可以访问非静态。
  • 静态方法中不可以使用this或者super关键字。
  • static方法是在编译的时候确定的,在类装入内存的时候也同时装入内存了;而非static方法是在类的实例化的时候装入内存的,其必须依赖于类的实例。

问题解答

  • static方法执行的时候,其所在的堆栈中是没有指向对象引用的任何信息的,而非static方法在调用的时候又必须要知道调用该方法的引用,所以在static方法中是没有办法调用非static方法的。
  • static方法中是不存在this的,而this是一个非常重要的指向对象引用的关键字(每个非static方法中都应该存在,并且指向了调用该方法的对象的引用;非static方法调用该类其他方法的时候实际上是用到了this.method),所以没有this的static方法是不可能直接调用该类中的非static方法的。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值