李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
Java中静态和非静态的区别
Leefs
2019-11-18 AM
2858℃
2条
# Java中静态和非静态的区别 ### 前言 前几天,有一个朋友问我静态和非静态的区别,于是自己就想着整理一下 ### 一、变量分类 通过是否被static关键字修饰将变量分成两种: + 1.通过static修饰的变量叫做静态变量,也叫类变量 + 2.没有static修饰的变量叫做非静态变量,也叫成员变量 ### 二、静态和非静态的使用 static可以修饰变量,方法和类,下面我们举几个例子进行比较分析 **1.修饰变量** ```java public class staticTest { static int a = 10;//静态变量 int b = 20;//成员变量 public static void main(String[] args) { staticTest st = new staticTest(); int b1 = st.b; int a1 = staticTest.a; int a2 = st.a; System.out.println("b1="+b1); System.out.println("a1="+a1); System.out.println("a2="+a2); } } ``` > 运行结果 ```java b1=20 a1=10 a2=10 ``` 静态变量a和成员变量b分别是主函数外的两个变量,在主函数中调用变量a和b的方法。 **静态变量:**`类名.变量名称`,例:(`staticTest.a`),也可以通过:创建对象、调用`对象.变量名称`进行使用,例:(`st.a`),但不推荐。 **成员变量:**创建对象、调用对象.变量名称进行使用,例:(`st.b`) **2.修饰方法** ```java public class staticTest { public static void dog(){//静态方法 System.out.println("wang~wang"); } public void cat(){//成员方法 System.out.println("miao~miao"); } public static void main(String[] args) { staticTest st = new staticTest(); st.cat(); st.dog(); staticTest.dog(); } } ``` > 运行结果 ```java miao~miao wang~wang wang~wang ``` **静态方法dog()**和**成员方法cat()**分别是主函数外的两个方法,在主函数中分别对`dog()`和`cat()`方法进行调用 **静态方法:**`类名.方法名称`,例:(`staticTest.dog()`),同时也可以通过创建对象、调用`对象.方法名称`进行使用,例:(`st.dog();`),但不推荐 **成员变量:**创建对象、调用`对象.方法名称`进行使用,例:(`st.cat()`) **3.修饰类** ```java public class staticTest { static class innerstatic{//静态内部类 public innerstatic(){ System.out.println("hello innerstatic"); } } class inner{//内部类 public inner(){ System.out.println("hello inner"); } } public static void main(String[] args) { staticTest st = new staticTest(); staticTest.innerstatic in = new staticTest.innerstatic(); staticTest.inner inner = st.new inner(); } } ``` > 运行结果 > ```java hello innerstatic hello inner ``` 静态内部类`innerstatic`和成员内部类`inner`分别是staticTest外部类的中的两个内部类,在主函数中分别对静态内部类`innerstatic`和成员内部类`inner`进行调用。 **静态内部类:**`外部类名称.内部类名称` 来对自身进行访问,例: `staticTest.innerstatic in = new staticTest.innerstatic();` **成员内部类:**`外部类对象.内部类名称`来完成对成员内部类的访问,例: `staticTest.inner inner = st.new inner();` 如果想对静态内部类和成员内部类做更深的了解,请查看小编之前的文章:[类和接口的嵌套(一)](https://lilinchao.com/archives/55.html)和[类和接口的嵌套(二)](https://lilinchao.com/archives/61.html) ### 三、静态变量在内存中的存放位置 #### 1.`JVM`内存一共分为四部分: > stack segment (栈) > > heap segment (堆) > > code segment (代码区) > > data segment (数据区) **stack segment (栈)** 保存基本数据类型的变量和自定义的对象的引用(不是对象),对象本身都存放在堆区中,被执行的方法开始时pull到栈中,当方法执行完后再push出栈。 ```java public static void main(String[] args) { String str = "123"; System.out.println(str); } ``` ```java public static void main(String[] args) { Test t = new Test(); } ``` 局部变量:如上面两个程序中的`str`和t存放于stack区。 ##### heap segment(堆) heap中存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令) ```java public static void main(String[] args) { Test t = new Test(); } ``` 当new 一个对象的时候,此对象放在了heap segment(堆)当中。t存放在stack中,而new Test()这个实实在在的对象是存在了heap中 ##### code segment(代码区) 类中的方法存放在该区 ##### data segment(数据区) static的变量或字符串常量存放在该区 #### 2. static变量和非static变量 static的变量与非static变量存放位置不一样,并且变量的访问权限也不一样。 **static变量是全局的,是类的所有对象都能访问的,是所有方法都可以访问的,无论是static修饰的方法还是非static方法都可以访问,没有限制。** **而非static变量是私有的,是有访问限制的,就是说是每个对象独有的,并且只有非static方法才可以访问。** ![staticdemo01.png][1] **static方法只能访问static的变量,没有权限访问非static变量。** ![staticdemo02.png][2] **static方法中声明的变量可以与非static变量并且是类的属性重名** ![staticdemo03.png][3] **方法中声明的变量可以与非static变量并且是类的属性重名** > 这是由于类的属性是存在与对象中的,是在heap中,而方法中的变量是存在与code 区中的,在不同的区中可以重名。 ![staticdemo04.png][4] **非static方法中可以方访问static变量。** > 这时因为static变量是共享的,任何方法,任何对象都可以访问 ![staticdemo05.png][5] **static方法可以访问static属性** ![staticdemo06.png][6] > static方法中声明的变量name存在code区,而类的属性中的name存在对象中,而对象存在于heap区。所以不会报错。 附:[参考文章](https://blog.csdn.net/expect521/article/details/77505541/) [1]: https://lilinchao.com/usr/uploads/2019/11/1096618861.png [2]: https://lilinchao.com/usr/uploads/2019/11/654063706.png [3]: https://lilinchao.com/usr/uploads/2019/11/2589930127.png [4]: https://lilinchao.com/usr/uploads/2019/11/1626729086.png [5]: https://lilinchao.com/usr/uploads/2019/11/721594514.png [6]: https://lilinchao.com/usr/uploads/2019/11/577477399.png
标签:
Java
,
JavaSE
非特殊说明,本博所有文章均为博主原创。
如若转载,请注明出处:
https://www.lilinchao.com/archives/201.html
上一篇
JVM学习(七)-- 初始化对于类与接口的异同深入解析
下一篇
Java匿名内部类(一)
取消回复
评论啦~
提交评论
已有 2 条评论
孤独这杯酒
大神赞一波
回复
2019-11-19 09:47
世纪风
@孤独这杯酒
就先写这么多了,不知道是不是你想要的
回复
2019-11-19 10:49
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
标签云
并发编程
栈
SpringCloudAlibaba
ClickHouse
JavaWeb
散列
Kafka
JavaWEB项目搭建
人工智能
Filter
FastDFS
CentOS
机器学习
Git
Docker
RSA加解密
正则表达式
Jquery
算法
DataWarehouse
并发线程
序列化和反序列化
工具
国产数据库改造
Shiro
排序
Spark Core
随笔
Nacos
BurpSuite
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
大神赞一波
就先写这么多了,不知道是不是你想要的