精华内容
下载资源
问答
  • 成员变量、类变量和静态变量三者的区别
    千次阅读
    2019-08-17 19:16:36

    实例变量(成员变量)

    在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。

    当一个对象被实例化之后,每个实例变量的值就跟着确定;

    实例变量在对象创建的时候创建,在对象被销毁的时候销毁;

    实例变量的值应该至少被一个方法、构造方法或者语句块引用,使得外部能够通过这些方式获取实例变量信息;

    实例变量可以声明在使用前或者使用后;

    访问修饰符可以修饰实例变量;

    实例变量对于类中的方法、构造方法或者语句块是可见的。一般情况下应该把实例变量设为私有(private修饰)。通过使用访问修饰符可以使实例变量对子类可见;

    实例变量具有默认值。数值型变量的默认值是0,布尔型变量的默认值是false,引用类型变量的默认值是null。变量的值可以在声明时指定,也可以在构造方法中指定;

    实例变量可以直接通过变量名访问。但在静态方法以及其他类中,就应该使用完全限定名;

    (区别于)局部变量

    定义在方法之中的变量称为局部变量;

    局部变量要先赋值,再进行运算,而实例变量均已经赋初值;(一大区别)

    实例变量的对象赋值为null;

    局部变量不允许范围内定义两个同名变量。实例变量的作用域在本类中完全有效,当被其他的类调用的时候也可能有效;

    实例变量和局部变量允许命名冲突;

    类变量

    类变量(也叫静态变量)是类中独立于方法之外的变量,用static修饰。

    (static表示“全局的”、“静态的”,用来修饰成员变量和成员方法,或者静态代码块(静态代码块独立于类成员,JVM加载类时会执行静态代码块,每个代码块只执行一次,按顺序执行))

    成员变量和类变量的关系区别

    [外链图片转存失败(img-7NdYk5FO-1566040524463)(C:\Users\lee\AppData\Roaming\Typora\typora-user-images\1566039815355.png)]

    1、两个变量的生命周期不同

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

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

    2、调用方式不同

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

    ​ 静态变量可以被对象调用,还可以被类名调用。

    3、别名不同

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

    ​ 静态变量也称为类变量。

    4、数据存储位置不同

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

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

    什么时候定义静态成员呢?或者说:定义成员时,到底需不需要被静态修饰呢?

    成员分两种:

    1、成员变量。(数据共享时静态化)

    ​ 该成员变量的数据是否是所有对象都一样:

    ​ 如果是,那么该变量需要被静态修饰,因为是共享的数据。

    ​ 如果不是,那么就说这是对象的特有数据,要存储到对象中。

    2、成员函数。(方法中没有调用特有数据时就定义成静态)

    ​ 如果判断成员函数是否需要被静态修饰呢?

    ​ 只要参考,该函数内是否访问了对象中的特有数据:

    ​ 如果有访问特有数据,那方法不能被静态修饰。

    ​ 如果没有访问过特有数据,那么这个方法需要被静态修饰。

    成员变量和静态变量的区别

    1、成员变量所属于对象。所以也称为实例变量。

    ​ 静态变量所属于类。所以也称为类变量。

    2、成员变量存在于堆内存中。

    ​ 静态变量存在于方法区中。

    3、成员变量随着对象创建而存在。随着对象被回收而消失。

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

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

    ​ 静态变量可以被对象调用,也可以被类名调用。

    在。随着对象被回收而消失。

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

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

    ​ 静态变量可以被对象调用,也可以被类名调用。

    所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。

    更多相关内容
  • Java实例变量和类变量

    万次阅读 多人点赞 2017-09-04 09:02:02
    其中局部变量可分为如下3。 形参:在方法签名中定义的局部变量,由方法调用者负责为其赋值,随方法的结束而消亡。 方法内的局部变量:在方法内定义的局部变量,必须在方法内对其进行显示初始化。这种类型的局部...

    Java程序的变量大体可分为成员变量和局部变量。其中局部变量可分为如下3类。

    • 形参:在方法签名中定义的局部变量,由方法调用者负责为其赋值,随方法的结束而消亡。
    • 方法内的局部变量:在方法内定义的局部变量,必须在方法内对其进行显示初始化。这种类型的局部变量从初始化完成后开始生效,随方法的结束而消亡。
    • 代码块的局部变量:在代码块内定义的局部变量,必须在代码块内对其进行显式初始化,这种类型的局部变量从初始化完成后开始生效,随代码的结束而消亡。

    局部变量的作用时间很短暂,它们都被存储在方法的栈内存中。类体内定义的变量被称为成员变量(英文是Field)。如果定义该成员变量时没有使用static修饰,该成员变量又被称为非静态变量或实例变量;如果使用了static修饰,则该成员变量又可被称为静态变量或类变量

    对于static关键字而言,从词义上来看,它是“静态”的意思。但从Java程序的角度来看,static的作用就是将实例成员变为类成员。static只能修饰在类里定义的成员部分,包括成员变量、方法、内部类、初始化块、内部枚举类。如果没有使用static修饰这里类里的成员,这里成员属于该类的实例;如果使用了static修饰,这些成员就属于类本身。从这个意义上看,static只能修饰类里的成员,不能修饰外部类,不能修改局部变量、局部内部类。

    表明上看,Java类里定义成员变量时没有先后顺序,但实际上Java要求定义成员变量时必须采用合法的前后引用。示例如下

    public class ErrorDef {
        int num1 = num2 + 5; //Cannot reference a field before it is defined
        int num2 = 20;
    }

    上面程序中定义num1成员变量的初始值时,需要根据num2变量的值进行计数,这就是“非法前后引用”。
    类似地,两个类变量也不允许采用这样“非法前后引用”,示例如下。

    public class ErrorDef {
        static int num1 = num2 + 5; //Cannot reference a field before it is defined
        static int num2 = 20;
    }

    但如果一个是实例变量,一个是类变量,则实例变量总是可以引用类变量,示例如下

    public class RightDef {
        int num1 = num2 + 5;
        static int num2 = 20;
    }

    上面程序中num1是一个实例变量,而num2是一个类变量。虽然num2位于num1之后被定义,但nun1的初始值却可根据num2计算得到。这是因为,num2变量是一个类变量,num1是实例变量,而类变量的初始化时机总是处于实例变量的初始化时机之前。所以,虽然源代码中先定义了num1,再定义了num2,但num2的初始化时机总是位于num1之前,因此num1变量的初始化可根据num2的值计算得到

    实例变量和类变量的属性

    使用static修饰的成员变量是类变量,属于该类本身;没有使用static修饰的成员变量是实例变量,属于该类的实例。在同一个JVM内,每个类只对应一个Class对象,但每个类可以创建多个Java对象。

    由于同一个JVM内每个类只对应一个Class对象,因此同一个JVM内的一个类的类变量只需一块内存空间;但对于实例变量而言,该类每创建一次实例,就需要为实例变量分配一块内存空间。也就是说,程序中有几个实例,实例变量就需要几块内存空间。

    下面程序可以很好地表现出来实例变量属于对象,而类变量属于类的特性。

    
    class Person {
        static int eyeNum;
        String name;
        int age;
    
        public void info() {
            System.out.println("Name: " + name + ", Age: " + age);
        }
    }
    
    
    public class FieldTest {
        public static void main(String[] args) {
            // 类变量属于该类本身,只要改类初始化完成,程序即可使用类变量
            Person.eyeNum = 2; // ①
    
            // 通过Person类访问 eyeNum类变量
            System.out.println("Person的eyeNum属性:" + Person.eyeNum);
    
            // 创建第一个Person对象
            Person p1 = new Person();
            p1.name = "zhangsan";
            p1.age = 22;
    
            System.out.println("通过p1变量访问eyeNum类变量:" + p1.eyeNum); // ②
            p1.info();
    
            // 创建第二个Person对象
            Person p2 = new Person();
            p2.name = "lisi";
            p2.age = 30;
            p2.info();
    
            // 通过p2修改Person类的eyeNum类变量
            p2.eyeNum = 4; // ③
    
            System.out.println("通过p1变量访问eyeNum类变量:" + p1.eyeNum);
            System.out.println("通过p2变量访问eyeNum类变量:" + p2.eyeNum);
            System.out.println("通过Person类访问eyeNum类变量:" + Person.eyeNum);
        }
    }

    上面程序中①行代码直接对Person类的eyeNum类变量赋值。这没任何问题,因为eyeNum类变量是属于Person类的,当Person类初始化完成后,eyeNum类变量也随之初始化完成。因此,程序即可对该类变量赋值,也可访问该类变量的值。

    执行①行代码之后,程序的内存分配如图所示。

    这里写图片描述

    一旦Person类初始化完成,程序即可通过Person类访问eyeNum类变量。除此之外,Java还允许通过Person类的任意实例来访问eyeNum类变量

    虽然Java允许通过Person对象来访问Person类的eyeNum类变量,但由于Person对象本身并没有eyeNum类变量(只有实例变量才属于Person实例),因此程序通过Person对象来访问eyeNum类变量时,底层依然会转换为通过Person访问eyeNum类变量。也就是说,不管通过哪个Person对象来访问eyeNum类变量,都与通过Person类访问eyeNum类变量的效果完全相同。因此,在②行代码处通过p1来访问eyeNum变量将再次输出2.

    执行完②行代码后,程序的内存分配如图

    这里写图片描述

    从图中可以看出,当程序创建Person对象时,系统不再为eyeNum类变量分配内存空间,执行初始化,而只为Person对象
    的实例变量执行初始化 – 因为实例变量才属于Person实例,而类变量属于Person类本身。

    当Person类初始化完成之后,类变量也随之初始化完成,以后不管程序创建多少个Person对象,系统不再为eyeNum类变量分配内存,但程序每创建一个Person对象,系统将再次为name、age实例变量分配内存,并执行初始化。

    当程序执行完③行代码之后,内存中再次增加了一个Person对象。当程序通过p2对eyeNum类变量进行赋值时,实际上依然是对Person类的eyeNum类变量进行赋值。此时程序的内存分配如图所示。

    这里写图片描述

    当Person类的eyeNum类变量被改变之后,程序通过p1、p2、Person类访问eyeNum类变量都将输出4。这是由于,不管通过哪个Person对象来访问eyeNum类变量,底层都将转换为通过Person来访问eyeNum类变量。由于p1和p2两个变量指向不同的Java对象,当通过它们访问实例变量时,程序将输出不同的结果。

    实例变量的初始化时机

    对于实例变量而言,它属于Java对象本身,每次程序创建Java对象时都需要为实例变量分配内存空间,并执行初始化。
    从程序运行的角度来看,每次创建Java对象都会为实例变量分配内存空间,并对实例变量执行初始化。
    从语法角度来看,程序可以在3个地方对实例变量执行初始化:

    • 定义实例变量时指定初始值
    • 非静态初始化块中对实例变量指定初始值
    • 构造器中对实例变量指定初始值

    其中第1、2种方式(定义时指定的初始值和非静态初始化块中指定的初始值)比第3种方式(构造器中指定初始值)更早执行,但第1、2中方式的执行顺序与他们在源程序中的排列顺序相同。

    
    class Cat {
        String name;
        int age;
    
        public Cat(String name, int age) {
            System.out.println("执行非静态初始化块");
            this.name = name;
            this.age = age;
        }
    
        {
            System.out.println("执行构造器");
            weight = 3.0;
        }
    
        double weight = 2.5;
    
        public String toString() {
            return "Name: " + name + ", Age: " + age + "Weight: " + weight;
        }
    }
    
    
    public class InitTst {
        public static void main(String[] args) {
            Cat cat1 = new Cat("tom", 3); // ①
            System.out.println(cat1);
    
            Cat cat2 = new Cat("jiafei", 2); // ②
            System.out.println(cat2);
        }
    }

    每当程序调用指定构造器来创建Java对象时,该构造器必然会获得执行的机会。除此之外,该类所包含的非静态初始化块将会获得执行的机会,而且总是在构造器执行之前获得执行。

    当程序执行①行代码创建第一个Cat对象的时候,程序将会先执行Cat类的非静态初始化块,再调用该Cat类的构造器来初始化该Cat实例。执行完①行代码后的内存分配如图所示。

    这里写图片描述

    从图中可以看出,该Cat对象的weight实例变量的值为2.5,二不是初始化块中指定的。这是因为,初始化块中指定初始值,定义weight时指定初始值,都属于对该实例变量执行的初始化操作,他们的执行顺序与它们的顺序相同。在本程序中,初始化块中对weight的赋值位于定义weight语句之前,因此程序将先执行初始化块中的初始化操作,执行完成后weight实例变量的值为3.0,然后再执行定义weight时指定的初始值,执行完成后weight实例变量的值为2.5。 从这个意义上来看,初始化块中对weight所指定的初始化值每次都将被2.5所覆盖。

    当执行②行代码再次创建一个Cat对象时,程序将再一次调用非静态初始化块、相应的构造器来初始化Cat对象。

    执行完②行代码后,程序的内存分配如图所示。

    这里写图片描述

    类变量的初始化时机

    实例变量属于Java类本身,只有当程序初始化该Java类时才会为该类的类变量分配内存空间,并执行初始化。
    从程序运行的角度来看,每JVM对一个Java类只初始化一次,因此Java程序每运行一次,系统只为类变量分配一次内存空间,执行一次初始化。
    从语法角度来看,程序可以在2个地方对类变量执行初始化:

    • 定义类变量时指定初始值
    • 静态初始化块中对类变量指定初始值。

    这两种方式的执行顺序与它们在源程序中的排列顺序相同。

    public class StaticInitTest {
        // 定义count类变量,定义时指定初始值
        static int count = 2;
    
        // 通过静态初始化块为name类变量指定初始值
        static {
            System.out.println("StaticInitTest的静态初始化块");
            name = "hello";
        }
    
        // 定义name类变量时指定初始值
        static String name = "itmyhome";
    
        public static void main(String[] args) {
            System.out.println("count类变量的值" + StaticInitTest.count);
            System.out.println("name类变量的值" + StaticInitTest.name);
        }
    }

    静态初始化块中为类变量指定初始值,每次运行该程序,系统将会对StaticInitTest类执行初始化:先为所有类变量分配内存空间,再按源代码中的排序执行静态初始化块中所指定的初始值和定义类变量时所指定的初始值.

    对于本例程序而已,静态初始化夸中对name变量的指定初始值位于定义name变量时指定初始值之前,因此系统先将name类变量赋值为“hello”,然后再将该name类变量赋值为“itmyhome”。每运行该程序一次,这个初始化过程只执行一次,因此运行上面程序将看到输出name类变量的值为“itmyhome”.

    下面程序更清楚地表现了类变量的初始化过程。首先定义了Price类,该Price类里有一个静态的initPrice变量,用于代表初始价格。每次创建Price实例时,系统会以initPrice为基础,减去当前打折价格(由discount参数代表)即得到该Price的currentPrice变量值

    
    class Price {
        // 类成员是Price实例
        final static Price INSTANCE = new Price(2.8);
    
        // 再定义一个类变量
        static double initPrice = 20;
    
        // 定义该Price的currentPrice实例变量
        double currentPrice;
    
        public Price(double distinct) {
            // 根据静态变量计算实例变量
            currentPrice = initPrice - distinct;
        }
    }
    
    
    public class PriceTest {
        public static void main(String[] args) {
            // 通过Price的INSTANCE访问currentPrice实例变量
            System.out.println(Price.INSTANCE.currentPrice); // ①
    
            // 创建Price实例
            Price p = new Price(2.8);
            // 通过创建的Price实例访问currentPrice实例变量
            System.out.println(p.currentPrice); // ②
        }
    }

    上面程序中①、②行代码都访问Price实例的currentPrice实例变量,而且程序都是通过new Price(2.8)来创建Price实例的。表面上看,程序输出两个Price的currentPrice都应该返回17.2(由20减去2.8得到),但实际上运行程序并没有输出两个17.2,而是输出-2.8和17.2

    如果仅仅停留在代码表面来看这个问题,往往很难得到正确的结果,下面从内存角度来分析这个程序。第一次用到Price类时,程序开始对Price类进行初始化,初始化分成以下2个阶段。

    • (1)系统为Price的两个类变量分配内存空间。
    • (2)按初始化代码(定义时指定初始化值和初始化块中执行初始值)的排列顺序对类变量执行初始化。

    初始化第一阶段,系统先为INSTANCE、initPrice两个类变量分配内存空间,此时INSTANCE、initPrice的默认值null和0.0。截止初始化进入第二个阶段,程序按顺序依次为INSTANCE、initPrice进行复制。对INSTANCE赋值时要调用Price(2.8),创建Price实例,此时立即执行程序中③代码为currentPrice进行赋值,此时initPrice类变量的值为0,因此赋值的结果是currentPrice等于-2.8。接着,程序再次将initPrice赋为20,但此时对INSTANCE的currentPrice实例变量以及不起作用了。

    当Price类初始化完成后,INSTANCE类变量引用到一个currentPrice为-2.8的Price实例,而initPrice类变量的值为20.0。当再次创建Price实例时,该Price实例的currentPrice实例变量的值才等于20.0

    展开全文
  • 二、类变量 也叫静态变量。 定义在类中、方法外,有关键字 static 修饰,有默认初始值。 可以通过对象调用,也可以通过类名调用。 生命周期与类共存亡。 对象的引用存放在方法区,如果用关键字 new 为引用类型的...

    一、实例变量

    也叫成员变量、全局变量。

    • 定义在类中、方法外,有默认初始值。
    • 通过对象的引用来访问实例变量。
    • 随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。

    二、类变量

    也叫静态变量。

    • 定义在类中、方法外,有关键字 static 修饰,有默认初始值。
    • 可以通过对象调用,也可以通过类名调用。
    • 生命周期与类共存亡。
    • 对象的引用存放在方法区,如果用关键字 new 为引用类型的静态变量分配对象,该对象在堆中的地址也会存放在方法区。!但是对象本身仍在堆内存中

    三、局部变量

    • 定义在方法中,或者方法的形参,没有初始化值。
    • 生命周期与方法共存亡。
    • 存放在栈中。局部的对象的引用所指对象在堆中的地址在存储在了栈中。

    举例:

    public class StaticObjTest {
        static class Test {
            static ObjectHolder staticObj = new ObjectHolder();//静态变量、类变量
            ObjectHolder instanceObj = new ObjectHolder();//实例变量、成员变量
            void foo() {
                ObjectHolder localObj = new ObjectHolder();//局部变量
                System.out.println("done");
            }
        }
    }
    
    • 静态变量staticObj 随着Test的类型信息存放在方法区
    • 成员变量instance0bj 随着Test的对象实例存放在Java堆
    • 局部变量localobj则是存放在foo() 方法栈帧的局部变量表中。
    • 三个对象的数据在内存中的地址都落在Eden区范围内,所以结论:只要是对象实例 即new() 必然会在Java堆中分配。

    再举个例子:

    public class  PersonDemo
    {
        public static void main(String[] args) 
        {   //局部变量p和形参args都在main方法的栈帧中
            //new Person()对象在堆中分配空间
            Person p = new Person();
            //sum在栈中,new int[10]在堆中分配空间
            int[] sum = new int[10];
        }
    }
    class Person
    {   //实例变量name和age在堆(Heap)中分配空间
        private String name;
        private int age;
        //类变量(引用类型)name1和"cn"都在方法区(Method Area)
        private static String name1 = "cn";
        //类变量(引用类型)name2在方法区(Method Area)
        //new String("cn")对象在堆(Heap)中分配空间
        private static String name2 = new String("cn");
        //num在堆中,new int[10]也在堆中
        private int[] num = new int[10];
        Person(String name,int age)
        {   
            //this及形参name、age在构造方法被调用时
            //会在构造方法的栈帧中开辟空间
            this.name = name;
            this.age = age;
        }
        //setName()方法在方法区中
        public void setName(String name)
        {
            this.name = name;
        }
        //speak()方法在方法区中
        public void speak()
        {
            System.out.println(this.name+"..."+this.age);
        }
        //showCountry()方法在方法区中
        public static void  showCountry()
        {
            System.out.println("country="+country);
        }
    }
    
    展开全文
  • 成员变量、类变量(静态变量)、局部变量的区别

    千次阅读 多人点赞 2017-08-03 20:31:04
    变量名首写字母使用小写,如果由多个单词组成,从第2个单词开始的其他单词的首写字母使用大写。 如果局部变量的名字和成员变量的名字相同, 要想在该方法中使用成员变量,... String name = "体重定义的name";
    变量名首写字母使用小写,如果由多个单词组成,从第2个单词开始的其他单词的首写字母使用大写。

    如果局部变量的名字和成员变量的名字相同, 要想在该方法中使用成员变量,必须使用关键字this

    [java]  view plain  copy
    1. class People {  
    2.     String name = "类体重定义的name";         //类中的成员变量并赋值  
    3.   
    4.     People(){  
    5.     }  
    6.       
    7.     public void speak() {  
    8.         String name = "类体方法中定义的name";       //在方法speak中定义和成员变量名字相同的name并赋值  
    9.         System.out.println(name);  
    10.         System.out.println(this.name);      //通过this来访问类中的成员变量  
    11.           
    12.     }  
    13. }  
    14.   
    15.   
    16. public class TestThis {                              //源文件中只能有一个类是public类,并且源文件的名字必须与这个类的名字完全相同,如  
    17.                                                          //果没有public类,那么源文件的名字只要和某个类的名字相同就可以了。  
    18.     public static void main(String[] args) {         
    19.         People myPeople = new People();  
    20.         myPeople.speak();  
    21.     }  
    22.   
    23. }  
    输出结果:

    成员变量和局部变量的区别

           成员变量:

              1、成员变量定义在类中,在整个类中都可以被访问。

              2、成员变量随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。

              3、成员变量有默认初始化值。

          局部变量:

              1、局部变量只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。

              2、局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放。

              3、局部变量没有默认初始化值 

          在使用变量时需要遵循的原则为:就近原则

          首先在局部范围找,有就使用;接着在成员位置找。



    成员变量和类变量的区别


    由static修饰的变量称为静态变量,其实质上就是一个全局变量。如果某个内容是被所有对象所共享,那么该内容就应该用静态修饰;没有被静态修饰的内容,其实是属于对象的特殊描述。

    不同的对象的实例变量将被分配不同的内存空间, 如果类中的成员变量有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说对象共享类变量。


    [java]  view plain  copy
    1. class MyAdd {  
    2.     int count = 0;          //成员变量计数器  
    3.     static int sum = 0;     //静态变量计数器  
    4.     String name;  
    5.       
    6.   
    7.     MyAdd(String name){  
    8.         this.name = name;  
    9.     }  
    10.       
    11.     public void myAddMethod() {    
    12.         count++;  
    13.         System.out.println(name+"调用成员变量后的值:"+count);  
    14.     }  
    15.       
    16.     public void staticAddMethod() {    
    17.         sum++;  
    18.         System.out.println(name+"调用类后变量的值:"+sum);  
    19.     }  
    20.       
    21.       
    22. }  
    23.   
    24.   
    25. public class TestThis {  
    26.   
    27.     public static void main(String[] args) {  
    28.         MyAdd add1 = new MyAdd("add1");  
    29.         MyAdd add2 = new MyAdd("add2");  
    30.           
    31.         add1.myAddMethod();  
    32.         add2.myAddMethod();  
    33.         add1.myAddMethod();  
    34.         add1.staticAddMethod();  
    35.         add2.staticAddMethod();  
    36.         add1.staticAddMethod();  
    37.     }  
    38.   
    39. }  

    输出结果:



    成员变量和类变量的区别:

       1、两个变量的生命周期不同

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

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

       2、调用方式不同

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

          静态变量可以被对象调用,还可以被类名调用。

       3、别名不同

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

          静态变量也称为类变量。

       4、数据存储位置不同

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

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



    static:★★★ 关键字,是一个修饰符,用于修饰成员(成员变量和成员函数)。

       特点:

       1、想要实现对象中的共性数据的对象共享。可以将这个数据进行静态修饰。

       2、被静态修饰的成员,可以直接被类名所调用。也就是说,静态的成员多了一种调用方式。类名.静态方式。

        3、静态随着类的加载而加载。而且优先于对象存在。

     

    弊端:

       1、有些数据是对象特有的数据,是不可以被静态修饰的。因为那样的话,特有数据会变成对象的共享数据。这样对事物的描述就出了问题。所以,在定义静态时,必须要明确,这个数据是否是被对象所共享的。

       2、静态方法只能访问静态成员,不可以访问非静态成员。

          因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。

       3、静态方法中不能使用this,super关键字。

          因为this代表对象,而静态在时,有可能没有对象,所以this无法使用。

     

    什么时候定义静态成员呢?或者说:定义成员时,到底需不需要被静态修饰呢?

    成员分两种:

       1、成员变量。(数据共享时静态化)

          该成员变量的数据是否是所有对象都一样:

          如果是,那么该变量需要被静态修饰,因为是共享的数据。 

          如果不是,那么就说这是对象的特有数据,要存储到对象中。 

       2、成员函数。(方法中没有调用特有数据时就定义成静态)

          如果判断成员函数是否需要被静态修饰呢?

          只要参考,该函数内是否访问了对象中的特有数据:

          如果有访问特有数据,那方法不能被静态修饰。

          如果没有访问过特有数据,那么这个方法需要被静态修饰。


    成员变量和静态变量的区别:

       1、成员变量所属于对象。所以也称为实例变量。

          静态变量所属于类。所以也称为类变量。

       2、成员变量存在于堆内存中。

          静态变量存在于方法区中。

       3、成员变量随着对象创建而存在。随着对象被回收而消失。

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

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

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

       所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据。



    成员变量:包括实例变量和类变量,用static修饰的是类变量,不用static修饰的是实例变量,所有类的成员变量可以通过this来引用。
    局部变量:包括形参,方法局部变量,代码块局部变量,存在于方法的参数列表和方法定义中以及代码块中。
     
    1.成员变量可以被public,protect,private,static等修饰符修饰,而局部变量不能被控制修饰符及 static修饰;两者都可以定义成final型。
     
    2.成员变量存储在堆,局部变量存储在栈。局部变量的作用域仅限于定义它的方法,在该方法的外部无法访问它。成员变量的作用域在整个类内部都是可见的,所有成员方法都可以使用它。如果访问权限允许,还可以在类的外部使用成员变量。
     
    3.局部变量的生存周期与方法的执行期相同。当方法执行到定义局部变量的语句时,局部变量被创建;执行到它所在的作用域的最后一条语句时,局部变量被销毁。类的成员变量,如果是实例成员变量,它和对象的生存期相同。而静态成员变量的生存期是整个程序运行期。
     
    4.成员变量在累加载或实例被创建时,系统自动分配内存空间,并在分配空间后自动为成员变量指定初始化值,初始化值为默认值,基本类型的默认值为0,复合类型的默认值为null。(被final修饰且没有static的必须显式赋值),局部变量在定义后必须经过显式初始化后才能使用,系统不会为局部变量执行初始化。
     
    5.局部变量可以和成员变量 同名,且在使用时,局部变量具有更高的优先级,直接使用同名访问,访问的是局部变量,如需要访问成员变量可以用this.变量名访问


    先看下面两段程序:

    程序一:
    public class Variable
    {
    int i;
    void test()
    {
       int j=8;
       if(j==i)
        System.out.println("相等");
       else
        System.out.println("不相等");
    }
    public static void main(String[] args)
    {
       Variable v=new Variable();
       v.test();
    }
    }

    程序二:
    public class Variable
    {
       void test()
    {
       int i;
       int j=8;
       if(j==i)
        System.out.println("相等");
       else
        System.out.println("不相等");
    }
    public static void main(String[] args)
    {
       Variable v=new Variable();
       v.test();
    }
    }

    ----------------------------------------------------------------------------------------------------------

    第一个程序很正常,编译时不会出错。第二个程序编译时会提示如下错误:

    D:\Program\java\test>javac Variable.java
    Variable.java:9: 可能尚未初始化变量 i
                    if(j==i)
                          ^
    1 错误

    之所以会出现这样的错误是因为:成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值

    ===========================================================

    类体分为两部分。变量定义部分所定义的变量被称为类的成员变量,在方法体中定义的变量和方法的参数都被称为局部变量

    java中成员变量和局部变量的区别

    1.成员变量可以被public,protect,private,static等修饰符修饰,而局部变量不能被控制修饰符及static修饰;两者都可以定义成final型
    2.成员变量存储在堆,局部变量存储在栈
    3.存在时间不同
    4.成员变量有默认值,(被final修饰且没有static的必须显式赋值),局部变量不会自动赋值
    -------------------------------------------------------------------------------------------------------------
    顾名思意了
    什么是局部,方法内部,块内部都是局部,执行指令退出那个局部,局部变量自动清除

    比如方法中,不用说
    块中
    {
      int i=0; //这是一个局部变量,它的作用范围就在其中 
    }

    成员变量就会涉及到谁的成员,类的成员?实例的成员?

    class A{
    int i=0; //实例的成员
    static j=1;//类的成员
    }

    static 的差别,是否依赖于实例而存在
    ----------------------------------------------------------------------------------------------------------

    成员变量:作为类的成员而存在,直接存在于类中。

    局部变量:作为方法或语句块的成员而存在,存在于方法的参数列表和方法定义中。

    局部变量在使用前必须被程序员主动的初始化,和此形成对比,系统中的成员变量则会被系统提供一个默认的初始值。所以在语法上,类的成员变量能够定义后直接使用,而局部变量在定义后先要赋初值,然后才能使用。

     

    所有类的成员变量可以通过this来引用。成员变量又分成俩中类型:实例变量和静态变量。静态变量在定义时要使用static关键字。



    展开全文
  • python中类变量和实例变量详解

    千次阅读 2020-05-23 16:23:30
    python中类变量和实例变量详解 在了解类变量和实例变量之前,首先要知道类变量和实例变量的定义。 类变量:可在类的所有实例之间共享的值,就是指不是单独分配给每个实例,实例可以调用类变量。 实例变量:实例化...
  • Java——类变量和实例变量的区别

    万次阅读 多人点赞 2019-04-29 15:47:01
    二是有static修饰的,称为类变量(静态变量)。 静态变量(类变量)具备以下特点: 随着类的加载而加载 优先于对象存在 被所有对象所共享 可以直接被类名调用 类变量和实例变量的区别是: 1,存放位置。 ...
  • 1.类变量 下面介绍类变量的两种定义方式、两种读取方式、在类里面的调用方式 定义 1.类里定义的,与构造函数、普通函数是一个级别缩进的。(下面例子里的num) 2.在类外定义的,直接用类名.变量名新增类变量。...
  • Python类定义字类变量与实例变量

    千次阅读 2018-01-19 11:02:01
    学过JAVA或C++等语言的程序员...Python类中定义的变量分为类变量和实例变量(也叫成员变量、对象变量),类变量直接定义在类里面(不在函数里面),前面不会有一个self修饰;相反,实例变量大都定义在实例函数里面,通
  • Python类变量和实例变量区别

    千次阅读 2019-07-25 19:01:41
    类变量:定义在类里面,通过类名或对象名引用,如果是通过对象名引用,会先找有没有这个同名的实例变量,如果没有,引用到的才是类变量类变量的更新,只能通过类名,形如 类名.a = 55 ,不要指望通过实例引用...
  • 初学Java,发现在对实例方法和类方法操作变量和对象操作方法的概念与原因模糊不清,做了一个思维导图。...包含为什么类方法只能操作类变量? 为什么只能通过对象调用实例方法? 为什么this不能出现在类方法中?等 ...
  • Java 基础之实例方法,实例变量,类方法,类变量

    千次阅读 多人点赞 2019-05-18 09:08:17
    实例变量(instance variable) 实例变量:或叫实例域、实例字段(instance field),或叫成员变量(member variable)。实例的变量,每个实例的变量可能不同。 ...类变量(class variable) 类...
  • java 成员变量和类变量的区别

    千次阅读 2018-03-16 11:13:09
    不同的对象的实例变量将被分配不同的内存空间, 如果类中的成员变量有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说对象共享类变量...
  • python3:类变量和实例变量的区别

    千次阅读 2018-10-19 13:48:36
    类变量又叫全局变量,是属于类的特性,实例先找实例化变量,然后再去找类变量. 但是 实例变量只是属于 实例化的变量, 但是 类变量 也可以用实例去调用. 如果类变量有多重继承关系, 就需要按照指定的路线进行查找. ...
  • 实例变量与类变量的区别

    万次阅读 多人点赞 2018-07-31 19:11:20
    实例变量也叫做对象变量,类变量也叫做静态变量 它们区别在于:实例变量为所属对象所私有,而类变量为所有对象所共有 如果一个对象将类变量的值进行改变,那么其他对象将不能改变他的值;而实例变量则是为对象所...
  • 不同的对象的实例变量将被分配不同的内存空间, 如果类中的成员变量有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说对象共享类变量...
  • java中类变量和实例变量

    万次阅读 多人点赞 2019-03-27 16:08:54
    b)类变量(以static修饰) 区别: 访问:实例变量是通过定义类的对象来访问。类变量可以通过类或类对象来访问。 生存周期 :实例变量与类对象生存周期共存亡。类变量与类共存亡。 变量修改:多个对象指向...
  • python中的类变量

    万次阅读 多人点赞 2018-04-24 17:44:35
    python中的类变量最近我参加了一次面试,面试官要求用python实现某个api,一部分代码如下class Service(object): data = [] def __init__(self, other_data): self.other_data = other_data 面试官说:“ data =...
  • Java 类变量和类方法

    万次阅读 2018-05-22 14:16:35
    一、类变量1、静态代码块 static{ } 静态代码块只会被执行一次;2、类定义的时候,类中变量创建在代码区,此时静态代码块会被自动执行;例子:package smm; public class LearnStatic { static int i=1; ...
  • Java三大变量分别是类变量、实例变量和局部变量

    千次阅读 多人点赞 2017-06-20 15:46:47
    类变量不仅可以直接通过类名+点操作符+变量名来操作,也可以通过类的实例+点操作符+变量来操作,大多数情况下,采用前者操作方式,一来不能够有效地使用该变量,二来能够表示该变量就是类变量。 2、...
  • 一、类变量和实例变量的定义 |-成员变量:把类内、方法体外定义的变量称为成员变量。 |-类变量:有static修饰,称为类变量(静态变量); |-随着类的加载而加载; |-优先于对象存在; |-被所有对象所共享; |-...
  • 成员变量和类变量(Java)

    千次阅读 2019-12-29 09:33:18
    变量定义 成员变量是定义在类中,方法体之外的变量。这种变量在创建对象的时候实例化。成员变量可以被类中方法、构造方法和特定类的语句块...类变量类变量也声明在类中,方法体之外,但必须声明为static类型。 ...
  • 什么是类变量

    千次阅读 2020-01-22 11:40:03
    类变量是指一个类的变量,通常为静态变量,而实例变量通常是动态的 类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果;而实例变量则属对象私有,某一个...
  • 一、类变量 1.1 可变变量作为类变量:对于列表、字典、自定义类这些可变变量,如果将其作为类变量,则是传引用。即所有对象的类变量公用一个内存地址。 1.2不可变变量作为类变量:对于INT,STRING这种不可变变量,...
  • 成员变量和类变量的区别

    千次阅读 2018-11-14 15:12:26
    不同的对象的实例变量将被分配不同的内存空间, 如果类中的成员变量有类变量,那么所有对象的这个类变量都分配给相同的一处内存,改变其中一个对象的这个类变量会影响其他对象的这个类变量,也就是说对象共享类变量...
  • java 简述类变量和实例变量的区别

    千次阅读 2019-06-05 12:42:26
    类变量也叫静态变量,也就是在变量前加了static 的变量; 实例变量也叫对象变量,即没加static 的变量; 类变量和实例变量的区别在于:类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后...
  • 内部类调用外部类变量

    千次阅读 2019-09-12 15:07:08
    要求:使用已知的变量,在控制台输出30,20,10。 class Outer { public int num = 10; class Inner { public int num = 20; public void show() { int num = 30; Sy...
  • 类变量:有效性主要和变量前的修饰符有关,例如private修饰就只对此类有效,public对所有包都有效。 存储位置: 成员变量:随着对象的创建而创建,对象消失则此变量也消失,存储于堆内存中。 局部变量:在方法被调用...
  • 原文地址:... Python-类变量,成员变量,静态变量,类方法,静态方法,实例方法,普通函数 #coding:utf-8 class class_name(object): class_var = 'I am a class variable'...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,253,624
精华内容 1,301,449
关键字:

类变量