static修饰的静态变量与实例变量的区别,及其在初始化和内存中的运行机制详解

1. 静态变量的定义

静态变量Static Variable)在计算机编程领域指在程序执行前系统就为之静态分配(也即在运行时中不再改变分配情况)存储空间的一类变量。

说明:静态变量(用static修饰),它所被分配的空间是一直伴随程序运行的,空间将会保持到程序的结束关闭,才会被释放。

2.用static修饰的静态变量与普通变量的区别

假若在定义一个类的过程中,定义了一个static修饰的变量,那么这个类在被加载的同时,被static修饰的变量就存在于内存当中了,这样一来就独立于该类的所有对象,被该类所有对象共享,将对象相关的变成了类相关,基于此静态变量也可以称之为类变量。

代码说明:

class Person

{
     // 定义一个实例变量
     public String name;
     // 定义一个类变量
     public static int eyeNum;

}

public class PersonTest

{
     public static void main(String[] args)
     {
         Person p1 = new Person();
         Person p2 = new Person();
         p1.name = "王";
         p2.name = "向";
         p1.eyeNum = 2;
         p2.eyeNum = 3;
         System.out.println("p1变量的name变量值是:" + p1.name
             + " p1对象的eyeNum变量值是:" + p1.eyeNum);
         System.out.println("p2变量的name变量值是:" + p2.name
             + " p2对象的eyeNum变量值是:" + p2.eyeNum);
     }

}

运行结果:

分析:

在此程序中,我们将eyeNum定义为静态变量(即类变量),而name定义为普通的实例变量。

当运行Person p1 = new Person()时,代码第一次使用Person类,因此需要加载这个Person类,在类准备阶段,系统将会为该类的类变量分配内存空间,并对其指定初始值。Person初始化完成后,系统将在对内存中为Person类分配一块内存区域。

系统接着创建Person对象,并将Person对象赋值给p1变量,在此时,Person对象里会包含名为name的实例变量,并对其指定初始值。在此,可以看出eyeNum并不属于Person对象,而是属于Person类。

接着执行Person p2 = new Person(),代码创建第二个Person对象,因为在第一次创建Person时,已经对Person进行了初始化,Person已经存在于对内存中了,因此,在此创建时,不需要再次进行初始化操作,创建过程同p1,在此不做示意图解释。

当执行该段代码时

p1.name = "王";
         p2.name = "向";

系统会向p1和p2所指向的实例变量分别赋值。

p1.eyeNum = 2;
         p2.eyeNum = 3;

当执行到p1.eyeNum = 2 时,将2赋值给类变量eyeNum,当执行到p2.eyeNum = 3时,又将变量3赋值给eyeNum,由于eyeNum静态变量对该类所有对象共享的,因此在执行p2.eyeNum = 3时,会将之前的eyeNum值进行覆盖,因此,输出p1.eyeNum和p2.eyeNum两个值的时候,都会显示最后的赋值结果3.

原文地址:https://www.cnblogs.com/Leo-Xia/p/10291180.html

时间: 2024-08-03 15:37:08

static修饰的静态变量与实例变量的区别,及其在初始化和内存中的运行机制详解的相关文章

java成员变量和局部变量的初始化和内存中的运行机制

成员变量: 当系统加载类或创建类的实例时,系统会自动为成员变量分配内存空间,并在分配内存空间后,自动为成员变量指定初始值. eyeNum是类属性.name是实例属性 所有person实例访问eyeNum都将访问person类的eyeNum属性.访问的是同一块内存.如果通过实例修改类属性,所有实例访问时都会改变. 局部变量: 局部变量定义后,必须经过显示初始化才能使用.这意味着定义了局部变量后,系统并未为这个变量分配内存空间,直到等到程序为这个变量赋值初始值时,系统才会给局部变量分配内存,并将初始

java 成员变量、局部变量、静态变量、类变量、非静态变量、实例变量、向前引用、非法向前引用、静态代码块、非静态代码块

①java类的成员变量有俩种: 一种是被static关键字修饰的变量,叫类变量或者静态变量 另一种没有static修饰,为成员变量 ②通俗点说: 类的静态变量在内存中只有一个,java虚拟机在加载类的过程中为静态变量分配内存,静态变量位于方法区,被类的所有实例共享.静态变量可以直接通过类名进行访问,其生命周期取决于类的生命周期. 而实例变量取决于类的实例.每创建一个实例,java虚拟机就会为实例变量分配一次内存,实例变量位于堆区中,其生命周期取决于实例的生命周期. 注意点: 1.JAVA中初始化

Java中的静态变量、实例变量和局部变量及其特征

变量类型 说明 特征 类变量(静态变量) 独立于方法之外的变量,用   static 修饰 类变量也称为静态变量,在类中以static关键字声明,但必须在方法构造方法和语句块之外.     无论一个类创建了多少个对象,类只拥有类变量的一份拷贝.     静态变量除了被声明为常量外很少使用.常量是指声明为public/private,final和static类型的变量.常量初始化后不可改变.     静态变量储存在静态存储区.经常被声明为常量,很少单独使用static声明变量.     静态变量在

java线程安全问题之静态变量、实例变量、局部变量

Java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如:"一个类在可以被多个线程安全调用时就是线程安全的". 此处不赘述了,首先给出静态变量.实例变量.局部变量在多线程环境下的线程安全问题结论,然后用示例验证,请大家擦亮眼睛,有错必究,否则误人子弟! 静态变量:线程非安全. 静态变量即类变量,位于方法区,为所有对象共享,共享一份内存,一旦静态

(转)java线程安全问题之静态变量、实例变量、局部变量

java多线程编程中,存在很多线程安全问题,至于什么是线程安全呢,给出一个通俗易懂的概念还是蛮难的,如同<java并发编程实践>中所说: 写道 给线程安全下定义比较困难.存在很多种定义,如:“一个类在可以被多个线程安全调用时就是线程安全的”. 此处不赘述了,首先给出静态变量.实例变量.局部变量在多线程环境下的线程安全问题结论,然后用示例验证,请大家擦亮眼睛,有错必究,否则误人子弟! 静态变量:线程非安全. 静态变量即类变量,位于方法区,为所有对象共享,共享一份内存,一旦静态变量被修改,其他对象

成员变量(实例变量)&amp;局部变量&amp;静态变量(类变量)的区别

成员变量(实例变量)&局部变量区别: (1)作用域 成员变量:针对整个类有效. 局部变量:只在某个范围内有效.(一般指的就是方法,语句体内) (2)存储位置 成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中. 局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中. 当方法调用完,或者语句结束后,就自动释放. (3)初始值 成员变量:有默认初始值. 局部变量:没有默认初始值,使用前必须赋值. 成员变量(实例变量)&静态变量(类变量)区别: A:调用方式 静态变

成员变量、实例变量、类变量、成员方法、实例方法、类方法的区别

简单来说:类体的定义包括成员变量的定义和方法的定义. 1.成员变量包括实例变量和类变量:而成员方法包括实例方法.类方法,当然还有一种特殊的构造方法.  2.类变量.类方法就是类中的变量.方法,必须是静态的,要加static:故其又称静态变量 .静态方法.3.成员变量.成员方法是对象或实例中的变量.方法,不加static:  类变量:静态域,静态字段,或叫静态变量,它属于该类所有实例共有的属性,在内存中只有一个地方存储这个变量.而且所有的实例都可以修改这个类变量的值(前提是这个类变量没 有被fin

java中类变量和实例变量的实质区别?

类变量和实例变量的区别 相对于static(静态的)或说类的, 本章开始提到的都是instance(实例的)或说对象的. 每个对象都有自己的一份儿对象域或实例域,相互之间没关系, 不共享. 我们可以从对象中访问实例变量. 类变量或说静态变量跟实例变量是不一样的,(视频下载) (全部书籍)不管创建了多少个对象,系统只为每个类变量分配一次存储空间.系统为类变量分配的内存是在执行main方法时马克-to-win, 就是在程序最最开始的时候(见下面StaticDemo的例子).所有的对象共享了类变量.可

iOS 成员变量,实例变量,属性变量的区别,联系

在ios第一版中: 我们为输出口同时声明了属性和底层实例变量,那时,属性是oc语言的一个新的机制,并且要求你必须声明与之对应的实例变量,例如: 注意:(这个是以前的用法) @interface MyViewController :UIViewController { UIButton *myButton; } @property (nonatomic, retain) UIButton *myButton; @end 在现在iOS版本中: 苹果将默认编译器从GCC转换为LLVM(low leve