精华内容
下载资源
问答
  • java对象对象引用变量

    千次阅读 多人点赞 2018-07-12 14:47:54
    基本类型的变量对象的引用变量 存取速度比堆要快,仅次于寄存器,栈数据可以共享 存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量 当超过变量的作用域后,Java...

    Java对象及其引用

    先搞清楚什么是堆,什么是栈。 
    Java开辟了两类存储区域,对比二者的特点

    存储区域存储内容优点缺点回收
    基本类型的变量和对象的引用变量存取速度比堆要快,仅次于寄存器,栈数据可以共享存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量当超过变量的作用域后,Java会自动释放掉该变量,内存空间可以立即被另作他用
    由new等指令创建的对象和数组可以动态地分配内存大小,生存期也不必事先告诉编译器由于要在运行时动态分配内存,存取速度较慢由Java虚拟机的自动垃圾回收器来回收不再使用的数据

    堆栈的存储特点决定了其中存储的数据类型。

    注意,栈内存储的除了基本类型的变量(int 这种类型的变量)还会存储对象的引用变量。java中,引用变量实际上是一个指针,它指向的是堆内存中对象实例。

    引用变量就相当于是为数组或对象起的一个名称,以后就可以在程序中使用栈中的引用变量来访问堆中的数组或对象。

     

     

    以下分解成了四个步骤。

    Case cc; '''在栈内存里面开辟了空间给引用变量cc,这时cc=null'''
    cc=new Case();
    '''
    1. new Case()在堆内存里面开辟了空间给Case类的对象,这个对象没有名字
    2. Case()随即调用了Case类的构造函数
    3. 把对象的地址在堆内存的地址给引用变量cc
    '''

    这样我们就明确了:

    • Java中,这里的“=”并不是赋值的意思,而是把对象的地址传递给变量;
    • 对象创建出来,其实连名字都没有,因此必须通过引用变量来对其进行操作。

    为了形象地说明对象、引用及它们之间的关系,可以做一个或许不很妥当的比喻。对象好比是一只很大的气球,大到我们抓不住它。引用变量是一根绳, 可以用来系汽球

    关于对象与引用之间的一些基本概念。

           初学Java时,在很长一段时间里,总觉得基本概念很模糊。后来才知道,在许多Java书中,把对象和对象的引用混为一谈。可是,如果我分不清对象与对象引用,

           那实在没法很好地理解下面的面向对象技术。把自己的一点认识写下来,或许能让初学Java的朋友们少走一点弯路。

           为便于说明,我们先定义一个简单的类:

           class Vehicle {

           int passengers;      

           int fuelcap;

           int mpg;

                       }

    有了这个模板,就可以用它来创建对象:

           Vehicle veh1 = new Vehicle();

    通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。

    1)右边的“new Vehicle”,是以Vehicle类为模板,在堆空间里创建一个Vehicle类对象(也简称为Vehicle对象)。

    2)末尾的()意味着,在对象创建后,立即调用Vehicle类的构造函数,对刚生成的对象进行初始化。构造函数是肯定有的。如果你没写,Java会给你补上一个默认的构造函数。

    3)左边的“Vehicle veh 1”创建了一个Vehicle类引用变量。所谓Vehicle类引用,就是以后可以用来指向Vehicle对象的对象引用。

    4)“=”操作符使对象引用指向刚创建的那个Vehicle对象。

    我们可以把这条语句拆成两部分:

    Vehicle veh1;

    veh1 = new Vehicle();

    效果是一样的。这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。

           在堆空间里创建的实体,与在数据段以及栈空间里创建的实体不同。尽管它们也是确确实实存在的实体,但是,我们看不见,也摸不着。不仅如此,

           我们仔细研究一下第二句,找找刚创建的对象叫什么名字?有人说,它叫“Vehicle”。不对,“Vehicle”是类(对象的创建模板)的名字。

           一个Vehicle类可以据此创建出无数个对象,这些对象不可能全叫“Vehicle”。

           对象连名都没有,没法直接访问它。我们只能通过对象引用来间接访问对象。

           为了形象地说明对象、引用及它们之间的关系,可以做一个或许不很妥当的比喻。对象好比是一只很大的气球,大到我们抓不住它。引用变量是一根绳, 可以用来系汽球。

           如果只执行了第一条语句,还没执行第二条,此时创建的引用变量veh1还没指向任何一个对象,它的值是null。引用变量可以指向某个对象,或者为null。

           它是一根绳,一根还没有系上任何一个汽球的绳。执行了第二句后,一只新汽球做出来了,并被系在veh1这根绳上。我们抓住这根绳,就等于抓住了那只汽球。

           再来一句:

           Vehicle veh2;

    就又做了一根绳,还没系上汽球。如果再加一句:

           veh2 = veh1;

    系上了。这里,发生了复制行为。但是,要说明的是,对象本身并没有被复制,被复制的只是对象引用。结果是,veh2也指向了veh1所指向的对象。两根绳系的是同一只汽球。

           如果用下句再创建一个对象:

    veh2 = new Vehicle();

    则引用变量veh2改指向第二个对象。

           从以上叙述再推演下去,我们可以获得以下结论:

    (1)一个对象引用可以指向0个或1个对象(一根绳子可以不系汽球,也可以系一个汽球);

    (2)一个对象可以有N个引用指向它(可以有N条绳子系住一个汽球)。

           如果再来下面语句:

           veh1 = veh2;

    按上面的推断,veh1也指向了第二个对象。这个没问题。问题是第一个对象呢?没有一条绳子系住它,它飞了。多数书里说,它被Java的垃圾回收机制回收了。

    这不确切。正确地说,它已成为垃圾回收机制的处理对象。至于什么时候真正被回收,那要看垃圾回收机制的心情了。

           由此看来,下面的语句应该不合法吧?至少是没用的吧?

    new Vehicle();

    不对。它是合法的,而且可用的。譬如,如果我们仅仅为了打印而生成一个对象,就不需要用引用变量来系住它。最常见的就是打印字符串:

        System.out.println(“I am Java!”);

    字符串对象“I am Java!”在打印后即被丢弃。有人把这种对象称之为临时对象。

           对象与引用的关系将持续到对象回收

    Java在运行时才处理别名引用

    欢迎关注下方公众号,一起交流,期待你的到来

    展开全文
  • 由static修饰的是类变量,类名.变量名 调用,也可以用对象.变量名调用 不是由static修饰的是实例变量,也就是对象成员变量, 对象.... //定义对象变量 private int age; public static void main(Str...

    由static修饰的是类变量,类名.变量名 调用,也可以用对象.变量名调用
    不是由static修饰的是实例变量,也就是对象成员变量, 对象.变量名 调用

    public class Variable {
    	//定义类变量
    	private  static String name ;;
    	//定义对象变量
    	private int age;
    	
    	public static void main(String[] args){
    		Variable p1 = new Variable();
    		Variable p2 = new Variable();
    		p1.name = "panda";
    		p1.age  = 16;
    		p2.name = "kongfu";
    		p2.age = 18;
    		System.out.println("-----"+Variable.name);
    		 
    	}
    }
    

    下面我们来逐步看内存情况

    1. Variable p1 = new Variable(); 第一次使用Variable这个类,系统会加载这个类,并且初始化,name为类变量,系统为类变量分配内存空间、并且赋初始值
    2. 类初始化完成后,系统会为Variable类创建一个对象,age属于实例变量,系统为age分配内存空间并指定初始值0,然后把Variable对象所在地址赋值给p1,即p1指向一个Variable对象。如下图
      在这里插入图片描述
    3. Variable p2 = new Variable();执行这行代码过程基本和 Variable p1 = new Variable(); 一毛一样,只是Variable类已经存在堆内存中了,不需要再进行加载、初始化、如下图
      在这里插入图片描述
    4. p1.age = 16; p2.age = 18; 当执行这两行代码时,即通过引用给各自对象成员变量赋值,没啥说的;重点在于p1.name = "panda" p2.name = "kongfu"; 这两行代码,通过对象来访问类变量并赋值,从上图可以看出,类变量归类管,在类的内存区中,对类的所有对象实例都是共享的,跟通过类来访问时一样的,所做的修改对所有对象都有影响,如下图
      在这里插入图片描述

    有猿友反应staic变量放得位置不对,
    找了几篇资料,jdk8之前静态变量确实是放在方法区中,8是把字符串池和静态变量放入堆中
    在这里插入图片描述

    运行时常量池得变化:
    在这里插入图片描述

    字符串常量池和静态变量存放位置得变化:
    在这里插入图片描述

    展开全文
  • JAVA 面向对象 成员变量和局部变量

    万次阅读 多人点赞 2016-07-20 18:08:42
    在 Java语言中, 根据定义变量位置的不同,可以将变量分成两大类:成员变量 局部变量 成员变量和局部变量的运行机制存在很大差异,下面我们看看差异在哪. 成员变量 成员变量指的是在类里定义的变量. 局部变量指的是...

    本页面更新日期: 2016年07月20日

    前言

    在 Java语言中, 根据定义变量位置的不同,可以将变量分成两大类:

    • 成员变量
    • 局部变量

    成员变量和局部变量的运行机制存在很大差异,下面我们看看差异在哪.

    成员变量

    成员变量指的是在类里定义的变量.
    局部变量指的是在方法里定义的变量.

    下面我给出Java程序中的变量划分图:

    这里写图片描述

    成员变量被分为类变量和实例变量两种.
    定义成员变量时没有 static 修饰符的就是实例变量.
    有static修饰符的就是类变量.

    其中, 类变量从该类的准备阶段起开始存在.
    直到系统完全销毁这个类,类变量的作用域与这个类的生存范围相同.
    而实例变量则从该类的实例被创建起开始存在,知道系统完全销毁这个实例.
    实例变量的作用域与对应实例的生存范围相同.

    小知识: 一个类在使用之前需要经过 类加载 / 类验证 / 类准备 / 类解析 / 类初始化 等几个阶段.
    关于类的生命周期, 我们以后会详细介绍.

    正是基于以上原因, 可以把类变量和实例变量统称为成员变量.
    其中, 类变量可以理解为 类成员变量, 它作为类本身的一个成员, 与类本身共存亡.
    实例变量则可以理解为 实例成员变量, 它作为实例的一个成员, 与实例共存亡.

    只要类存在, 程序就可以访问该类的类变量.
    在程序中通过如下语法访问:

    类.类变量

    只要实例存在, 程序就可以访问该实例的实例变量.
    在程序中通过如下语法访问:

    实例.实例变量

    当然, 类变量也可以让该类的实例来访问.
    通过实例访问类变量的语法如下:

    实例.类变量

    但由于这个实例并不拥有这个类变量.
    因此它访问的并不是这个实例的变量,依然是访问它对应类的类变量.
    也就是说, 如果通过一个实例修改了类变量的值, 由于这个类变量并不属于它.
    而是属于它对应的类. 因此, 修改的依然是类的类变量.
    与通过该类来修改类变量的结果完全相同.
    这会导致该类的其它实例来访问这个类变量时也获得这个被修改过的值.

    上面啰嗦了半天, 不过其内容我们之前已经体验过, 你能明白就行.

    下面我写个程序, 定义了一个 Person 类, 在这个 Person 类中定义两个成员变量.
    一个类变量: eyeNum
    一个实例变量: name
    程序通过 PersonTest 类来创建 Person 实例.
    并分别通过 Person 类 和 Person 实例来访问实例变量和类变量.

    class Person
    {
      //定义一个类变量
      public static int eyeNum;
      //定义一个实例变量
      public String name;
    }
    
    public class PersonTest
    {
      public static void main(String[] args)
      {
        //第一次主动使用 Person 类, 该类自动初始化, 则 eyeNum 变量开始起作用, 输出 0
        System.out.println("Person 的 eyeNum 类变量的值:" + Person.eyeNum);
        //创建 Person 对象
        Person p = new Person();
        //通过 Person 对象的引用 p 来访问 Person 对象的 name 实例变量
        //并通过实例访问 eyeNum 类变量
        System.out.println("p 对象的 name 变量的值是:" + p.name + "p 对象的 eyeNum 变量的值是:" + p.eyeNum);
        //直接为 name 实例变量赋值
        p.name = "孙悟空";
        //通过 p 访问 eyeNum 类变量, 依然是访问 Person 的 eyeNum 类变量
        p.eyeNum = 2;
        //再次通过 Person 对象来访问 name 实例变量 和 eyeNum 类变量
        System.out.println("p 对象的 name 变量值是:" + p.name + "p 对象的 eyeNum 变量值是:" + p.eyeNum);
        //前面通过 p 修改了 Person 的 eyeNum, 此处的 Person.eyeNum 将输出 2
        System.out.println("Person 的 eyeNum 类变量值:" + Person.eyeNum);
        Person p2 = new Person();
        //p2 访问的 eyeNum 类变量依然引用 Person 类的, 因此依然输出 2
        System.out.println("p2 对象的 eyeNum 类变量值:" + p2.eyeNum);
      }
    }
    

    从上面程序可以看出, 成员变量无须显式初始化.
    只要为一个类定义了 类变量 或 实例变量.
    系统就会在这个类的准备阶段或创建该类的实例时进行默认初始化.
    成员变量默认初始化的赋值规则与我们之前讲的 数组动态初始化 时数组元素的赋值规则完全相同.

    我们还可以得知, 类变量的作用域 比 实例变量的作用域 更大.
    实例变量随实例的存在而存在.
    而类变量则随类的存在而存在.
    实例也可以访问类变量, 同一个类的所有实例访问类变量时.
    实际上访问的是该类本身的同一个变量, 也就是说, 访问了同一片内存区.

    注意!!!
    Java 允许实例访问 static 修饰的类变量本身就是一个错误.
    因此建议你以后看到通过实例来访问 static 修饰的类变量时, 都可以将它替换成通过类本身来访问. 这样程序的可读性 / 明确性 都会大大提高!

    局部变量

    局部变量根据定义形式的不同, 可以分为如下三种:

    • 形参: 在定义方法签名时定义的变量, 形参的作用域在这个方法内有效.
    • 方法局部变量: 在方法体内定义的局部变量, 它的作用域就是从定义该变量的地方生效, 到该方法结束时失效.
    • 代码块局部变量: 在代码块中定义的局部变量, 这个局部变量的作用域从定义该变量的地方生效, 到该代码块结束时失效.

    与成员变量不同的是, 局部变量除了形参之外, 都必需显式初始化.
    也就是说, 必需先给方法局部变量和代码块局部变量指定初始值, 否则不可以访问它们.
    下面我写个定义代码块局部变量的程序.

    public class BlockTest
    {
      public static void main(String[] args)
      {
        {
          //定义一个代码块局部变量 a
          int a;
          //下面代码将会出现错误, 因为 a 变量没有初始化
          System.out.println("代码块局部变量 a 的值:" + a);
        }
        //下面试图访问 a 变量, 但 a 变量的作用域根本无法涉及这里
        System.out.println(a);
      }
    }
    

    上面的代码是一个错误示例, 如果你写出来还要运行的话, 只能说你 too yang to simple.
    从上面代码可以看出, 只要离开了 代码块局部变量 所在的代码块, 这个局部变量就没法用了.

    对于方法局部变量, 其作用域从定义该变量开始, 直到该方法结束.
    下面我写个 方法局部变量的作用域 示例.

    public class MethodLocalVariableTest
    {
      public static void main(String[] args)
      {
        //定义一个方法局部变量 a
        int a;
        //下面代码将会出现错误, 因为 a 变量没有初始化
        System.out.println("方法局部变量 a 的值:" + a);
      }
    }
    

    下面我们说形参.
    形参的作用域时整个方法体内有效, 而且形参也无须显式初始化.
    形参的初始化在调用该方法时由系统完成, 形参的值由方法的调用者负责指定.

    在同一个类里, 成员变量的作用域是整个类内有效.
    一个类里不能定义两个同名的成员变量.
    就算一个是类变量, 一个是实例变量也不行.

    一个方法里不能定义两个同名的成员变量.
    方法局部变量与形参名也不能同名.
    同一个方法中不同代码块内的代码块局部变量可以同名.

    如果先定义代码块局部变量, 后定义方法局部变量.
    前面定义的代码块局部变量与后面定义的方法局部变量是可以同名的.

    Java允许局部变量和成员变量同名.
    如果方法里的局部变量和成员变量同名, 局部变量会覆盖成员变量.
    如果需要在这个方法里引用被覆盖的成员变量.
    可以使用 this (对于实例变量) 或 类名(对于类变量) 来作为调用者.
    下面, 我写个程序.

    public class VariableOverrideTest
    {
      //定义一个 name 实例变量
      private String name = "猪八戒";
      //定义一个 price 类变量
      private static double price = 78.0;
      //主方法, 程序的入口
      public static void main(String[] args)
      {
        //方法里的局部变量, 局部变量覆盖成员变量
        int price = 65;
        //直接访问 price 变量, 将输出 price 局部变量的值.
        System.out.println(price);
        //使用类名作为 price 变量的调用者, 访问被覆盖的 类变量
        System.out.println(VariableOverrideTest.price);
        //运行 info 方法
        new VariableOverrideTest().info();
      }
      public void info()
      {
        //方法里的局部变量, 局部变量覆盖成员变量
        String name = "孙悟空";
        //直接访问 name 变量, 将输出 孙悟空
        System.out.println(name);
        //使用 this 来作为 name 的调用者, 访问 实例变量
        System.out.println(this.name);
      }
    }
    

    从上面代码可以看出, 当局部变量覆盖成员变量时.
    依然可以在方法中显式指定 类名和this 作为调用者来访问被覆盖的成员变量, 这使得变成更加自由.
    不过, 不过, 不过 . 你应该尽量避免这种局部变量和成员变量同名的情形. (想个名字真的有那么难么 - - )

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

    当系统加载类或创建该类的实例时.
    系统将自动为成员变量分配内存空间.
    并在分配内存空间后, 自动为成员变量指定初始值.

    下面通过代码来创建两个实例(非完整代码,能明白就行).
    同时配合示意图来说明 Java 成员变量的初始化和内存中的运行机制.

    //创建第一个 Person 对象
    Person p1 = new Person();
    //创建第二个 Person 对象
    Person p2 = new Person();
    //分别为两个 Person 对象的 name 实例变量赋值
    p1.name = "孙悟空";
    p2.name = "皮卡丘";
    //分别为两个 Person 对象的 eyeNum 类变量赋值
    p1.eyeNum = 2;
    p2.eyeNum = 3;

    下面开始解读:
    当程序执行第一行代码 Person p1 = new Person(); 时
    如果这行代码是第一次使用 Person 类.
    则系统会加载并初始化这个类.
    在类的准备阶段.
    系统将会为该类的类变量分配内存空间,并指定默认初始值.
    当 Person 类初始化完成后, 系统内存中的存储示意图如下:

    这里写图片描述

    从上图可以看出.
    当 Person 类初始化完成后.
    系统将在堆内存中为 Person 类分配一块内存区.
    在这块内存区中, 包含了 保存 eyeNum 类变量的内存.
    并设置 eyeNum 的默认初始值为: 0

    系统接着创建了一个 Person 对象.
    并把这个 Person 对象赋给 p1 变量.
    Person 对象里包含了名为 name 的实例变量.
    实例变量是在创建实例时分配内存空间并指定初始值的.
    当创建了第一个 Person 对象后, 系统内存中的存储示意图如下:

    这里写图片描述

    从上图可以看出, eyeNum 类变量并不属于 Person 对象.
    它是属于 Person 类的.
    所以创建第一个 Person 对象时并不需要为 eyeNum 类变量分配内存(废话…)
    系统只为 name 实例变量分配了内存空间.
    并指定默认初始值: null

    接着执行 Person p2 = new Person();
    代码创建第二个 Person 对象.
    此时因为 Person 类已经存在于堆内存了.
    所以不需要对 Person 类进行初始化(废话…Java 会那么傻么…)
    创建第二个 Person 对象 与 创建第一个 Person 对象并没有什么不同.

    当程序执行 p1.name = “孙悟空”; 时
    将为 p1 的 name 实例变量赋值.
    也就是让堆内存中的 name 指向 “孙悟空” 字符串.
    我们之前说过, 字符串也是一种引用变量. 所以你懂的.
    执行完成后, 两个 Person 对象在内存中的存储示意图如下:

    这里写图片描述

    从上图可以看出, name 实例变量是属于单个 Person 实例的.
    因此, 修改第一个 Person 对象的 name 实例变量时仅仅与 p1 对象有关.
    与 Person 类和其它 Person 对象没有任何关联.
    同理, 修改第二个 Person 对象 p2 的 name 实例变量时, 也与 Person 类和其它 Person 对象无关.

    直到执行 p1.eyeNum = 2 时
    此时呢, 就是犯大忌了. 你拿 对象来操作类变量了. 不过为了教学演示, 我拿自己当典型.
    从我们看过的图当中, 可以知道.
    Person 的对象根本没有保存 eyeNum 这个变量.
    通过 p1 访问的 eyeNum 类变量.
    其实还是 Person 类的 eyeNum 类变量.
    因此, 此时修改的是 Person 类的 eyeNum 类变量.
    修改成功后, 内存中的存储示意图如下:

    这里写图片描述

    从上图可以看出.
    不管通过哪个 Person 实例来访问 eyeNum 类变量.
    它们访问的其实都是同一块内存.
    所以就再次提醒你.
    当程序需要访问 类变量时.
    尽量使用类作为主调, 而不要使用对象作为主调.
    这样可以避免歧义, 提高程序的可读性.

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

    局部变量定义后.
    必需经过显式初始化后才能使用.
    系统不会为局部变量执行初始化.
    这意味着,定义局部变量之后,系统并未为这个变量分配内存控件.
    直到等程序为这个变量赋初始值时.
    系统才会为局部变量分配内存,并将初始值保存到这块内存中去.

    与成员变量不同,局部变量不属于任何类或实例.
    因此它总是保存在其所在的方法的栈内存中.
    如果局部变量是基本类型变量,则直接把这个变量的值保存在该变量对应的内存中.
    如果局部变量是引用类型的变量,则这个变量里存放的就是地址.
    通过该地址引用到该变量实际引用的对象或数组.

    变量的使用规则

    对于新手来说.
    什么时候使用类变量?
    什么时候使用实例变量?
    什么时候使用方法局部变量?
    什么时候使用代码块局部变量?
    这种选择比较困难,如果仅仅从程序的运行结果来看,大部分时候都可以直接使用类变量或实例变量来解决问题.无须使用局部变量.
    实际上这种做法非常错误.
    因为定义一个成员变量时,成员变量将被放置到堆内存中.
    成员变量的作用域将扩大到类存在范围或对象存在范围,这种返回的扩大有两个害处.

    • 增大了变量的生存时间,这将导致更大的内存开销(如果你以后开发Android,大内存开销会让你的APP无情被用户卸载)
    • 扩大了变量的作用域,这不利于提高程序的内聚性. (什么是内聚性?)

    让我们做个对比, 这样更好理解.

    public class ScopeTest01
    {
        //定义一个类成员变量作为循环变量
        static int i;
        public static void main(String[] args)
        {
            for(i = 0; i < 10; i++)
            {
                System.out.println("Hello");
            }
        }
    }
    public class ScopeTest02
    {
        public static void main(String[] args)
        {
            //定义一个方法局部变量作为循环变量
            int i;
            for(i = 0; i < 10; i++)
            {
                System.out.println("Hello");
            }
    
        }
    }
    public class ScopeTest03
    {
        public static void main(String[] args)
        {
            //定义一个代码块局部变量作为循环变量
            for(int i = 0; i < 10; i++)
            {
                System.out.println("Hello");
            }
        }
    }

    从程序的运行结果上来看, 这三者完全相同.
    但程序的效果则有很大差异.
    第三个程序最符合软件开发规范:
    对于一个循环变量而言, 只需要它在循环体内有效即可.
    因此只需要把这个变量放在循环体内(也就是在代码块内定义), 从而保证这个变量的作用域仅仅在该代码块内.

    我们要根据实际需要,来决定变量的作用域.例如下面的例子:

    • 如果需要定义的变量是用于描述某个类或对象的固有信息的.例如人的身高 / 体重等信息. 它们时人对象的固有信息, 每个人对象都具有这些信息. 这种变量应定义为成员变量.如果这种信息对于这个类的所有实例完全相同,或者说它是类相关的,例如人类的眼睛数量,这种类相关的信息就应该定义为类变量.如果信息和实例相关,例如人的身高 / 体重等, 每个人实例的身高 / 体重可能不同, 这种信息是实例相关的, 就应该定义为实例变量.

    即使在程序中使用局部变量, 也应该尽可能的缩小局部变量的作用范围.
    局部变量的作用范围越小, 它在内存里停留的时间就越短, 程序性能就越好.
    因此, 能用代码块局部变量的地方,就坚决不要使用方法局部变量.

    展开全文
  • 对象与对象变量

    千次阅读 2018-08-29 22:32:09
    要想使用对象,就必须首先构造对象,并指定其初始状态。然后对对象应用方法。  在java程序设计语言中,使用构造器构造新实例,构造器是一种特殊的方法,用来构造并初始化对象。下边看一个例子,在java库中包含一个...

             要想使用对象,就必须首先构造对象,并指定其初始状态。然后对对象应用方法。

             在java程序设计语言中,使用构造器构造新实例,构造器是一种特殊的方法,用来构造并初始化对象。下边看一个例子,在java库中包含一个Date类,他的对象将描述一个时间点,例如:“ December 31,1991,23:23:23 GMT”。

              构造器的名字应该与类名相同,因此Date类的构造器的名字为Date。要想构造一个Date对象,需要在构造器前面加上new操作符,如下显示:

             

    new Date();

     这个表达式构造了一个新对象。这个新对象被初始化为当前的日期和时间。

              如果需要的话也可以将一个对象传递给一个方法:

             System.out.println(new Date());

             或者,也可以将一个方法应用于刚刚创建的对象,Date类中有一个tostring方法。这个方法将返回一个字符串描述的日期格式,下面我们来举一个简单的例子:

    String s = new Date().toString();

            在上面两个例子中,够早的对象仅使用了一次,通常,希望构造的对象多次使用,因此,需要将对象存放在一个变量中;

            Date birhday = new Date();

            对象与对象变量之间存在着一个重要的区别。如,语句

       

       Date deadline;//deadline不是任何对象
    

    定义一个对象变量deadline,他可以引用Date类型的对象,但是,一定要认识到;变量deadline不是一个对象,实际上也没有引用对象,此时,不能讲任何Date方法应用于这个变量上。语句:

    s = deadline。toString();//not yet

    将产生编译错误。

            必须首先初始化变量deadline,这里有两个选择。淡然,可以用新构造的对象初始化这个变量;

    deadline = new Date();
    

            也可以让这个变量引用一个已经存在的对象;

            deadline = birthday;

    现在这两个对象引用同一个对象:

           一定要认识到:衣蛾对象变量并没有实际包含一个对象,而是引用一个对象。

          任何对变量的值都是对存储在另外一个地方的一个对象的引用。new操作符的返回值也是一个引用。例如下句:

    Date deadline = new Date();

    有两部分,表达式new Date()构造了一个Date类型的对,并且它的值是对新创建对象的引用,这引用存在变量deadline中

    可以显示的将对象变量设置为 null , 表明这个对象变量目前没有引用任何对象。

    deadline = null;
    ....
    if(deadline !=null)
        System.out.println(deadline);

            如果讲一个方法应用于一个值为null的对象上,那么就会产生运行是错误

    birthday = null;
    String s = birthday.toString();//runtime error

    局部变量不会自动的初始化为null,而必须通过调用new或将他们设置为null进行初始化。

     

    展开全文
  • JAVA - 对象与对象变量

    千次阅读 2018-06-11 14:26:22
    对象变量Date deadline;定义了一个对象变量deadline,它可以引用Date类型的对象。但是,一定要认识到:变量deadline不是一个对象,实际上也没有引用对象。此时,不能将任何 Date 方法应用于这个变量上。可以显式地将...
  • js给对象添加变量属性

    万次阅读 2018-11-21 15:44:49
    1、js创建一个对象或者在原有对象上添加一个已知属性,并给这个属性赋值,写法如下: let obj = {'a1':'a1'}; obj['a2'] = 'a2'; console.log(obj);//输出{'a1':'a1','a2':'a2'};  2、添加一个变量属性,并赋值...
  • Python的类变量和对象变量声明解析

    千次阅读 2018-02-14 23:43:57
    Python的类和C++一样,也都是存在两种类型的变量,类变量和对象变量!前者由类拥有,被所有对象共享,后者由每个对象独有。这里我主要想讨论一下他们的声明办法。 首先说的是对象变量: 只要是声明在类的语句块...
  • Java对象和引用变量

    万次阅读 多人点赞 2016-08-31 00:45:30
    对于引用变量的深层含义,未必在初学的时候就能深刻理解, 所以理解好下面这两句话的真正含义非常重要Case cc=new Case();... 基本类型的变量对象的引用变量 存取速度比堆要快,仅次于寄存器,栈
  • 例如: Dog a=new Dog(); 引用变量a的作用是获得new Dog()所创建对象的位置或者说是地址吗
  • Ruby对象变量和常量

    千次阅读 2016-01-11 13:40:09
    Ruby操作的数据主要有部分:对象、类、变量、常量.对象在Ruby中表示数据的基本单位称为对象,在Ruby中一切都是对象. 常用对象: 数值对象 2、3.14、-5等表示数字的对象,另外还有矩阵、复数、素数、公式的对象. ...
  • 全局对象和全局变量

    千次阅读 2018-01-09 10:48:00
    在JavaScript中,通常window是全局对象,而Node.js的全局对象是global,所有全局变量都是global对象的属性,如:console、process等。 一、全局对象与全局变量 global最根本的作用是作为全局变量的宿主。满足以下...
  • 指向对象成员变量的指针

    万次阅读 2016-04-16 20:46:01
    指向对象成员变量的指针
  • 对于刚接触不久面向对象的真小白童鞋来说,类的对象对象的实例,对象的引用,引用变量的问题以及莫过于没得对象虽然博主也没得对象,本文将逐个逐个讲解! 1.何谓对象? 在Java中有一句比较流行的话,叫做“万物皆...
  • 1 指向对象的常指针变量与指向常对象的指针变量区别  Time * const p; //指向对象的常指针变量 p的值(p的指向)不能修改  const Time *p; //指向常对象的指针变量,p指向的类对象的值不能通过p来修改 1.1 ...
  • 在java中如果类的成员变量设置为私有的,一般情况下是不允许直接访问这个变量的,但是有了反射之后,就可以直接获取该变量的名称和变量值1. 访问成员变量(1)先定义一个用户实体类public class User { private int ...
  • 对象变量和方法 在OPC UA中,最重要的节点类别是对象变量和方法。 1. 节点类别为对象 节点类别为对象的节点用于(构成)地址空间结构。 对象不包含数据,使用变量对象公开数值。 对象可用于分组管理对象、...
  • java中,对象,还有所有的new出来的对象都是存放在堆里。  方法存放在方法体中。  基本类型的变量的数据和对象的引用存放在栈中  ...
  • js--变量对象VO,活动对象AO

    千次阅读 2016-10-23 15:00:40
    变量对象VO变量对象VO是与执行上下文相关的特殊对象,用来存储上下文的函数声明,函数形参和变量。在global全局上下文中,变量对象也是全局对象自身,在函数上下文中,变量对象被表示为活动对象AO。变量对象VO存储...
  • 指向常对象的指针变量和指向对象的常指针 1,指向常对象的指针变量 指向常对象的指针变量可以指向一个已经申明为常对象变量,此时只能用指向常对象的指针变量指向它;也可以指向一个非常对象变量,而此时可...
  • 一、类变量和实例变量的定义 |-成员变量:把类内、方法体外定义的变量称为成员变量。 |-类变量:有static修饰,称为类变量(静态变量); |-随着类的加载而加载; |-优先于对象存在; |-被所有对象所共享; |-...
  • 在javascript中当使用typeof方法来判断[]和{}时,返回值都是’object’,那么如何来判断一个变量是数组还是对象呢?这里记录两种方法: 利用toString()方法 Object.prototype.toString.call({}) // [object ...
  • Java对象与引用变量

    千次阅读 2019-08-19 14:59:26
    基本类型的变量对象的引用变量 存取速度比堆要快,仅次于寄存器,栈数据可以共享 存在栈中的数据大小与生存期必须是确定的,缺乏灵活性。栈中主要存放一些基本类型的变量 当超过变量的作用域后,Java会自动释放掉...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,654,320
精华内容 1,061,728
关键字:

对象是变量吗