为什么使用static的类方法不需要new

JAVA加载过程

总觉得有无数想记录的东西但又觉得没什么需要记下来的。
但又不能坏了一周一篇的目标,再三思考下决定写一些基础干货。
基础扎实的话就会和计算机有某种共鸣——你猜测应该是什么样的,实际上计算机就是什么样的

static静态成员

这是我觉得目前以来最重要的java东西——理解静态成员。(本文不讲java实践,只讲java理论)
之前学习一直懵懵懂懂,只是学习了java的规则语法。虽然可以满足日常编程却总是提不起兴趣,缺乏创造力,没有创造力的职业我是坚决拒绝的,所以我一次又一次的从头学习java,这是我第四次从头学起了。
但是直到今天看到看到static ,仿佛和计算机有了某种共鸣,所以本文从static开始讲解java代码运行过程。

从static学习java编译过程

JVM加载顺序摘要:

  1. 加载所有类(类是默认加载的)
  2. 加载主函数(即main函数)

稍稍延申一下:

JAVA代码的加载过程简简单单的就这两步,但是还是颇有深意的。

  1. 加载所有类
    即就是说,类是在加载java代码时候就已经加载,并写入内存中的。
  2. 加载主函数
    即就是说,其他函数是不加载的。
    也就是说,其他函数只是逻辑存在,内存中并不真正的存在。
  3. 并没有加载任何对象和变量
    即所有对象都存在于逻辑中,并不存在。
    不存在的东西当然是不能调用的。同样的不能调用方法,也就丧失了方法存在的意义。

对于此java给出了两个解决方案:

  1. 实例化成员
    实例化(即就是执行new操作指令),实例化在JVM的操作就是——将执行new操作的东西(方法或者变量)写进内存中。一般来说抛开访问控制凡是内存中的东西都是可以直接调用的。
  2. 静态成员
    声明静态成员的关键字是static。JVM的操作是——在加载优先级等同于类,加载类的同时就会加载static成员。也就是说static的成员已经存在内存中了就可以进行直接调用。
    所以静态变量又称为类变量。

总结static

首先static的成员是在类加载的时候初始化的,JVM的CLASSLOADER的加载,首次主动使用加载,而非static的成员是在创建对象的时候,即new 操作的时候才初始化的;

先后顺序是先加载,才能初始化,那么加载的时候初始化static的成员,此时非static的成员还没有被加载必然不能使用,而非static的成员是在类加载之后,通过new操作符创建对象的时候初始化,此时static 已经分配内存空间,所以可以访问!

简单点说:静态成员属于类,不需要生成对象就存在了.而非静态需要生成对象才产生.所以静态成员不能直接访问非静态.

下面说说静态的特点:

  1. 着类的加载而加载
    也就是,说静态会随着类的消失而消失,说明静态的生命周期最长
  2. 先于对象的存在
    明确一点:静态是先存在的对象是后存在的
  3. 所有对象共享
  4. 以直接被类名多调用

实例变量和类变量的区别

  1. 放位置
    变量随着类的加载存在于方法区中,实例变量随着对象的对象的建立存在于堆内存里
  2. 命周期
    变量生命周期最长,随着“类”的加载而加载,随着类的消失而消失,实例变量随着“对象”的消失而消失

静态的使用注意事项:

  1. 静态方法只能访问静态成员(包括成员变量和成员方法)
    静态方法可以访问静态也可以访问非静态
  2. 态方法中不可以定义this,super关键字。
    静态优先于对象存在,所以静态方法中不可以出现this,super关键字
  3. 函数是静态的。

静态的利弊

利:对对象的共享数据进行单独空间的存储,节省空间,没有必要每一个对象中都存储一份可以直接被类名所调用
弊:生命周期过长,访问出现局限性(只能访问静态)

从内存角度理解java的基础语法

首先需要理解不是java代码本身占用的空间就是内存空间。真正写入内存的也并不是java代码,只是变量。
学过汇编的人应该大致知道,基层语言只是一些指令。

  1. 为什么主函数一定是静态的
    如之前所说,不是静态的成员不会预先加载。
    假如没有static关键词:编译器会主动加载所有的类,可是加载完类之后呢?
    虽然写了很多方法,可是都是逻辑的方法并不是实际存在的方法,所以这个类这是一个摆设而已,如果不被调用的话。
    所以主函数一定得是静态的,作为整个编译的开始。
  2. 为什么需要实例化呢?
    接上,主函数加载之后,主函数需要调用其他的方法,其他类才能实现这个代码包本身的价值
    那么问题来了,怎么调用呢?
    之前说了java只能调用内存中的东西,如果不写入内存是不能调用的否则会报错。
    如果要写入内存就要执行new指令。
    所以我们调用类的方法时候需要实例化:类名 变量名 = new 构造函数();
    java中本应该是:类名 变量名 = new 类名();
    为了深入理解我一般记上面的语法。
  3. 为什么静态的方法只能调用静态的成员变量(方法)呢?
    如很上很上所说,静态优先存在于普通成员。
    只有存在的东西才能调用存在的东西。不存在的东西是不能调用不存在的东西的。
    所以静态方法只能调用静态成员。
    不过换言之,如上所说“只有存在的东西才能调用存在的东西”
    那么如果给普通成员实例化不就存在了吗?
    恭喜你已经回举一反三了。事实上就是如此。
    这就是为什么静态方法调用静态方法不用实例化,而非静态方法调用静态方法需要实例化。

总结

java运行基本过程:

  1. 加载所有类预加载,但不加载类的方法
  2. 加载所有的static成员(即就是加载主函数)
  3. 主函数里运行,主函数实例化谁就把谁写进内存。
  4. 主函数调用哪个方法就调用哪个方法。

感谢鼎鼎的鼎力相助

  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值