在平时开发当中,我们经常会遇见static关键字。这篇文章就把java中static关键字的使用方法的原理进行一个深入的分析。先给出这篇文章的大致脉络:

首先,描述了static关键字去修饰java类、方法、变量、代码块的方法然后,从底层分析static关键字,接下来,给出static的一些使用场景和案例最后,对static进行一个总结,包括和普通变量的区分。

OK,开始今天的文章。

一、static关键字的基本用法

1、static关键字基本概念

我们可以一句话来概括:方便在没有创建对象的情况下来进行调用。

也就是说:被static关键字修饰的不需要创建对象去调用,直接根据类名就可以去访问。对于这个概念,下面根据static关键字的四个基本使用来描述。然后在下一部分再来去分析static的原理,希望你能认真读完。

2、static关键字修饰类

java里面static一般用来修饰成员变量或函数。但有一种特殊用法是用static修饰内部类,普通类是不允许声明为静态的,只有内部类才可以。下面看看如何使用。

如果没有用static修饰InterClass,则只能new 一个外部类实例。再通过外部实例创建内部类。

3、static关键字修饰方法

修饰方法的时候,其实跟类一样,可以直接通过类名来进行调用:

4、static关键字修饰变量

被static修饰的成员变量叫做静态变量,也叫做类变量,说明这个变量是属于这个类的,而不是属于是对象,没有被static修饰的成员变量叫做实例变量,说明这个变量是属于某个具体的对象的。

我们同样可以使用上面的方式进行调用变量:

5、static关键字修饰代码块

静态代码块在类第一次被载入时执行,在这里主要是想验证一下,类初始化的顺序。

父类静态变量

父类静态代码块

子类静态变量

子类静态代码块

父类普通变量

父类普通代码块

父类构造函数

子类普通变量

子类普通代码块

子类构造函数

代码验证一下:

首先我们定义一个父类

然后定义一个子类

看个结果

二、深入分析static关键字

上面我们只是描述了一下static关键字的基本使用场景,下面主要解析一下static关键字的深层原理。要理解static为什么会有上面的特性,首先我们还需要从jvm内存说起。我们先给出一张java的内存结构图,然后通过案例描述一下static修饰的变量存放在哪?

从上图我们可以发现,静态变量存放在方法区中,并且是被所有线程所共享的。这里要说一下java堆,java堆存放的就是我们创建的一个个实例变量。

堆区:

1、存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)

2、jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身

栈区:

1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中

2、每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。

3、栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。、

方法区:

1、又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。

2、方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。

下面通过一个案例说明一下,从内存的角度来看,static关键字为什么会有这样的特性。

首先我们定义一个类

接下来我们从内存的角度出发,看看

从上面可以看到,我们的方法在调用的时候,是从方法区调用的,但是堆内存不一样,堆内存中的成员变量lastname是随着对象的产生而产生。随着对象的消失而消失。静态变量是所有线程共享的,所以不会消失。这也就能解释上面static关键字的真正原因。

下面对static关键字进行一个小结:

(1)特点:

1、static是一个修饰符,用于修饰成员。(成员变量,成员函数)static修饰的成员变量 称之为静态变量或类变量。

2、static修饰的成员被所有的对象共享。

3、static优先于对象存在,因为static的成员随着类的加载就已经存在。

4、static修饰的成员多了一种调用方式,可以直接被类名所调用,(类名.静态成员)。

5、static修饰的数据是共享数据,对象中的存储的是特有的数据。

(2)成员变量和静态变量的区别:

1、生命周期的不同:

成员变量随着对象的创建而存在随着对象的回收而释放。

静态变量随着类的加载而存在随着类的消失而消失。

2、调用方式不同:

成员变量只能被对象调用。

静态变量可以被对象调用,也可以用类名调用。(推荐用类名调用)

3、别名不同:

成员变量也称为实例变量。

静态变量称为类变量。

4、数据存储位置不同:

成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。

静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。

(3)静态使用时需要注意的事项:

1、静态方法只能访问静态成员。(非静态既可以访问静态,又可以访问非静态)

2、静态方法中不可以使用this或者super关键字。

3、主函数是静态的

好了,static关键字就介绍道这里,谢谢您的支持,如有问题,还请批评指正

深入分析Java中的关键字static的更多相关文章

  1. Java中this、static关键字的内存图解

    Java中的关键字有很多,abstract  default  goto*  null  switch  boolean  do  if  package  nchronzed  break  dou ...

  2. Java中的关键字 transient

    先解释下Java中的对象序列化 在讨论transient之前,有必要先搞清楚Java中序列化的含义: Java中对象的序列化指的是将对象转换成以字节序列的形式来表示,这些字节序列包含了对象的数据和信息 ...

  3. 【转】java中volatile关键字的含义

    java中volatile关键字的含义   在java线程并发处理中,有一个关键字volatile的使用目前存在很大的混淆,以为使用这个关键字,在进行多线程并发处理的时候就可以万事大吉. Java语言 ...

  4. Java中native关键字

    Java中native关键字 标签: Java 2016-08-17 11:44 54551人阅读 评论(0) 顶(23453) 收藏(33546)   今日在hibernate源代码中遇到了nati ...

  5. 深入分析 Java 中的中文编码问题

    登录 (或注册) 中文 IBM 技术主题 软件下载 社区 技术讲座 打印本页面 用电子邮件发送本页面 新浪微博 人人网 腾讯微博 搜狐微博 网易微博 Digg Facebook Twitter Del ...

  6. [转]深入分析 Java 中的中文编码问题

    收益匪浅,所以转发至此 原文链接: http://www.ibm.com/developerworks/cn/java/j-lo-chinesecoding/ 深入分析 Java 中的中文编码问题 编 ...

  7. Java中this关键字的使用

    本文介绍了在Java中this关键字的作用于使用方法 当局部变量和成员变量重名时,在方法中使用this时,表示的是该方法所在类中的成员变量.(this指的是当前对象自己) 如:public class ...

  8. Java中this关键字在构造方法中的使用

    1. Java中this关键字代表对象本身.用this关键字可以在类的内部调用属性和方法,这样代码的可读性比较高,因为它明确的指出了这个属性或方法的来源. 2. 同时在构造函数中也可以使用this关键 ...

  9. 慕课网-安卓工程师初养成-2-1 Java中的关键字

    来源:http://www.imooc.com/code/1176 Java 中常用关键字: 问:这么多,记不住啊......-_-|| 答:现在不需要你记住所有,混个眼熟即可,在学习的过程中,你会逐 ...

随机推荐

  1. CS5211替代LT7211 DP转LVDS芯片方案 替代龙迅LT7211方案

    LT7211是一种用于虚拟现实/显示应用的高性能C/DP1.2至LVDS芯片方案.LT7211支持DP1.2输入,LT7211可以配置为1.2.4车道,还支持车道交换功能.自适应均衡使其适用于长电缆应 ...

  2. Nginx_配置文件nginx.conf配置详解

    user nginx nginx ; # Nginx用户及组:用户 组.window下不指定 worker_processes 8; # 工作进程:数目.根据硬件调整,通常等于CPU数量或者2倍于CP ...

  3. centos7 自动交互expect 安装使用

    1.安装 https://www.cnblogs.com/rocky-AGE-24/p/7256800.html 安装expect命令 两种方式yum安装 yum -y install expect ...

  4. c# - 接口的写法与基本调用

    1.前言 接口与Java基本一样 2.操作 (1)看路径结果 (2) 接口源码: namespace ConsoleApp1 { public interface ILogin { void Eat( ...

  5. RabbitMQ --- 直连交换机 【 有回调方法,获取消费结果 】

    1.前言 上一随笔详细记录了直连交换机的方法,发送的消息是异步的,如果消息未被消费者消费,那么可以一直存在消息队列中. 那么有没有办法做一个回调,当消息被消费后,被通知消息成功被消费者消费啦? 答案是 ...

  6. Linux上天之路(六)之Linux文件管理

    文件与文件夹的操作 1) 新建 2)改名 3)查看 4)删除 5)拷贝 6)移动 1. 文件的操作 文件的新建:touch filename 文件的改名:mv 文件的查看:ls 文件内容的查看:cat ...

  7. 《剑指offer》面试题37. 序列化二叉树

    问题描述 请实现两个函数,分别用来序列化和反序列化二叉树. 示例:  你可以将以下二叉树: 1 / \ 2 3 / \ 4 5 序列化为 "[1,2,3,null,null,4,5]&quo ...

  8. github与gitlab创建新仓库

    github创建新仓库 然后根据下一页的命令提示进行即可 gitlab创建新仓库 git init git remote add origin git@***.***.**.**:user/proje ...

  9. 🏆【Alibaba中间件技术系列】「RocketMQ技术专题」Broker服务端自动创建topic的原理分析和问题要点指南

    前提背景 使用RocketMQ进行发消息时,一般我们是必须要指定topic,此外topic必须要提前建立,但是topic的创建(自动或者手动方式)的设置有一个开关autoCreateTopicEnab ...

  10. 【记录一个问题】android opencl c++: 不要Context, CommandQueue类的赋值函数

    一开始代码中这样写了: cl::Context ctx = cl::Context(CL_DEVICE_TYPE_GPU, NULL); cl::CommandQueue queue= cl::Com ...