李林超博客
首页
归档
留言
友链
动态
关于
归档
留言
友链
动态
关于
首页
Java
正文
Java中静态和非静态的区别
Leefs
2019-11-18 AM
4036℃
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://lilinchao.com/archives/201.html
上一篇
JVM学习(七)-- 初始化对于类与接口的异同深入解析
下一篇
Java匿名内部类(一)
评论已关闭
栏目分类
随笔
2
Java
326
大数据
229
工具
31
其它
25
GO
47
NLP
4
标签云
正则表达式
CentOS
并发线程
Java阻塞队列
Zookeeper
前端
Java编程思想
哈希表
Scala
持有对象
算法
ClickHouse
SpringBoot
线程池
Http
查找
SpringCloudAlibaba
Java
Redis
随笔
Filter
机器学习
字符串
Typora
GET和POST
Netty
MyBatis-Plus
Livy
pytorch
Beego
友情链接
申请
范明明
庄严博客
Mx
陶小桃Blog
虫洞
评论已关闭