`
dtoneczw
  • 浏览: 26939 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

java变量的赋值与传递

    博客分类:
  • java
阅读更多
编了这么多年的JAVA,竟然还在这些基础知识上吃跟斗,磋啊。。


1 数据类型
  java的数据类型有两类:
  . PrimitiveType(简单类型)
  . ReferenceType(引用类型)

  1.1 PrimitiveType(简单类型)
  (参考:langspec-3.0/typesValues.html#4.2)

  PrimitiveType的分类如下所示:
       PrimitiveType:
        NumericType
        boolean

     NumericType:
        IntegralType
        FloatingPointType

       IntegralType: one of
        byte short int long char

       FloatingPointType: one of
        float double

       PrimitiveType是java预定义的类型,并且使用保留字命名。比如int、long、float等。由此看来其包装类不算PrimitiveType。
       1.2 ReferenceType(引用类型)
       (参考:langspec-3.0/typesValues.html#4.3)
       ReferenceType有三种类型:类、接口、和数组。

       2. 变量
       (参考:langspec-3.0/typesValues.html#4.12)
       A variable is a storage location and has an associated type, sometimes called its compile-time type, that is either a primitive type (§4.2) or a reference type (§4.3).
       变量是关联于特定类型的存储单元,所关联的类型有时叫做变量的编译时类型,即,既可以是简单类型也可以是引用类型。
       2.1 简单类型变量
       A variable of a primitive type always holds a value of that exact primitive type.
       简单类型的变量总是执持简单类型的值。
       2.2 引用类型变量
       A variable of a class type T can hold a null reference or a reference to an instance of class T or of any class that is a subclass of T. A variable of an interface type can hold a null reference or a reference to any instance of any class that implements the interface.
       类型是T的类的变量可以执持null引用,或者类T及其子类的实例引用。接口类型的变量可以执持null引用,或者任何实现该接口的类的实例引用。
       注:与langspec2.0不同的是,3.0引入了泛型的概念,其中有Type Variable的概念,上面的T就是一个Type Variable。
       3.赋值与传递
       如上所述,可以得出下面结论:
       1)      对于简单类型变量的赋值是按值传递。就是说直接把数值存放到变量的存储单元里。
       2)      对于引用类型的变量,赋值是把原对象的引用(可以理解为入口地址),存放在变量的存储单元里。
       3.1 对象的赋值
       简单类型的赋值很容易理解,这里仅讨论对象的赋值。所有引用类型的实例就是我们常说的对象。
       可以这样说,除了null以外,任何变量的初始赋值都是分两步:
       1)      创建对象实例
       2)      把对象实例的引用赋值给变量。

比如:
       Object o1 = new Object();
       3.2 传递
       传递是通过变量之间的赋值实现的。在以前的回贴中我说过这样一句话,单纯从变量的角度看,变量之间的赋值是值传递。现在我解释一下我的观点。

       先举一个例子:
           // java中所有的类的基类默认为Object,在此不赘述。
           class Object1 {}
      
           class Object2 {}
          Object o1, o2;
           o1 = new Object1();
           o2 = o1;
           o2 = new Object2();
       这时候,o1的类型是什么?是Object1还是Object2?正确答案是Object1。

再举一个例子:
           class Word {
               String word;
               public Word(String word){
                  this.word = word;
              }
               public void print(){
                  System.out.println(word);
              }
           }
           Word o1, o2;
           o1 = new Word("Every Day");
           o2 = o1;
           o2 = new Word("Every Night!");
           w1.print();
       会出现什么结果?"Every Day" 还是 "Every Night!"?仍然是"Every Day"。
       这里面有一个很多人特别是初学者忽视了的观点 ―― 变量可以引用对象,但变量不是对象。什么是对象?对象初始化之后,会占用一块内存空间,严格意义上讲,这段内存空间才是对象。对象创建于数据段,而变量存在于代码段;对象的入口地址是不可预知的,所以程序只能通过变量来访问对象。
       回到我们的问题上来,第一句
       o1 = new Word("Every Day");
       首先创建一个Word实例,即对象,然后把“引用”赋值给o1。
       第二句
       o2 = o1;
       o1把对象的引用赋值给o2,注意赋的值是对象的引用而不是o1自身的引用。所以,在的三句
       o2 = new Word("Every Night!");
       就是又创建一个新对象,再把新对象的引用赋值给o2。
       因为o1和 o2之间是值传,所以,对o2的改变丝毫不会影响到o1。
       也有一种情况好像是影响到了o1,我们继续上面的例子,给Word增加一个方法
           class Word {
               String word;
               public Word(String word){
                  this.word = word;
              }
               public void print(){
                  System.out.println(word);
              }
               public void setWord(String word){
                  this.word = word;
              }
           }
           Word o1, o2;
           o1 = new Word("Every Day");
           o2 = o1;
           o2.set Word("Every Night!");
           o1.print();
       这时的结果是"Every Night!"。

       那么,这是改变了o1吗?从严格意义上讲,不是。因为o1只是保存对象的引用,执行之后,o1还是持有该对象的引用。所以,o1没变,变的是o1所引用的对象。
       3.3 final变量能改变吗?
       好了,我再出道题目:
           final Word o3 = new Word("Every Day!");
           o3.setWord("Every Night!");
       能通过编译吗?对于final的定义大家都知道,o3是相当于一个常量,既然是常量,怎么能再改变呢?
       答案是肯定的,能。道理我想大家也明白,这里不罗嗦了。
       3.4 包装类的赋值与传递
       以前看过文章说,对于java基本类型及其包装类采用值传递,对于对象采用引用传递。从langspec看,首先包装类不是PrimitiveType,那就只能是ReferenceType,而ReferenceType的变量保存的是引用。既然保存的是引用,也就无从传递数值。那么,这两个观点矛盾吗?
       首先,肯定是langspec正确。
       其次,虽然前一观点在原理上有错误,但却不影响正常使用。
       为什么会出现这种情况?这是因为这些包装类具有一个简单类型的特征,即,不可改变。以String为例,看一下API Specification,不会找到能够改变String对象的方法。任何输出上的改变都是重建新的String对象,而不是在原对象基础上改变。改变的是变量的内容,即,不同对象的引用。
分享到:
评论

相关推荐

    NDKC调用Java函数传参或获取变量

    NDK开发时,C/C++调用Java的...获取int类型和String类型变量并重新赋值: https://blog.csdn.net/niuba123456/article/details/80990063 获取静态变量: https://blog.csdn.net/niuba123456/article/details/80990237

    Java开发技术大全(500个源代码).

    localVSmember.java 局部变量与成员变量同名问题示例 onlyTest.java 对象传值示例 otherClass.java 从类的外部访问对象的成员 showInstVar.java 演示不同的对象拥有不同的成员变量 showMain.java 演示main方法...

    《Java和Android开发实战详解》第2到5章源代码-by 南邮-陈杨

    5.2.4 值传递与引用传递 84 5.3 类变量和变量作用域 86 5.3.1 Java的类变量 86 5.3.2 Java的变量作用域 87 5.4 递归程序设计 89 5.4.1 递归方法概述 89 5.4.2 递归的阶乘函数 89 5.5 Math类及其类...

    head first java

    对象的声明与赋值 可回收堆空间 数组 习题 4 对象的行为 操作对象状态的方法 方法参数与返回类型 值传递 Getters与Setters 封装 数组中的引用 习题 5 超强力方法 创建战舰游戏 简单版 编写伪码 测试 编写程序 完成版...

    robotframework——变量文件.pdf

    如果这个函数存在, Robot Framework将调⽤该函数, 并且预期返回的结果是Python的字典类型或者Java中的 Map 类型, 其中变量的名称是键, ⽽值就是变量的值。 2.1 ⽰例1: rf⽤例: 执⾏⽅法⼀: 执⾏⽅法⼆: 执⾏⽅法...

    java基础案例与开发详解案例源码全

    3.1.3 变量的声明和赋值33 3.1.4 变量应用实例33 3.2 数据的分类34 3.2.1 Java中的八种基本数据类型34 3.2.2 普及二进制36 3.2.3 进制间转换37 3.2.4 基本数据类型间转换38 3.2.5 数据类型应用实例38 3.2.6 引用数据...

    Head First Java 目录1

    声明变量Primitive主数据类型Java关键字引变量对象的声明与赋值可回收堆空间数组4 对象的为操作对象状态的法法参数与返回类型值传递Getters与Set

    Java 语言基础 —— 非常符合中国人习惯的Java基础教程手册

    和行为应为与变量和方法相对应。自行车的状态:数度是 10mp(每小时 10 米),步度是 90rpm (每分钟 90 转),当前传动装置是第 5 个齿轮。再面向对象的程序设计中,这些数据应放在 变量中。自行车的行为:刹车,...

    java编程基础,应用与实例

    5.6 静态变量与静态方法 70 5.7 成员与静态方法的关系 71 5.8 包与导入 72 5.9 访问控制符 74 5.10 重载 77 5.11 构造函数 79 5.12 类的初始化 83 5.12.1 静态块 84 5.12.2 实例块 84 5.13 巩固...

    定义一个圆类circle,它有一个变量radius(半径)。从键盘输入数据,通过构造函数的参数传递给radius,编程计算并输出圆的的周长和面积。但是,必须确保输入的数据不为复数。

    定义一个圆类circle,它有一个变量radius(半径)。从键盘输入数据,通过构造函数的参数传递给radius,编程计算并输出圆的的周长和面积。但是,必须确保输入的数据不为复数。

    JAVA语言程序设计【高清版】.pdf

    64 5.2.2 默认的构造方法 66 5.3 定义方法 67 5.3.1 方法定义格式 68 5.3.2 按值传递 71 5.4 类的继承 72 5.4.1 继承的定义 73 5.4.2 多态性与转换对象 74 5.5 继续讨论Java的关键字 77 5.5.1 ...

    java基础知识下载

    变量:是java 程序中的基本存储单元,它的定义包括变量名、变量类型和作用域几个部分。其定义格式如下: typeSpecifier varName[=value[,varName[=value]…]; 如:int count; char c='a'; 变量的作用域指明可访问...

    java 编程入门思考

    A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...

    疯狂JAVA讲义

    第1章 Java概述 1 1.1 Java语言的发展简史 2 1.2 Java的竞争对手及各自优势 4 1.2.1 C#简介和优势 4 1.2.2 Ruby简介和优势 4 1.2.3 Python的简介和优势 5 1.3 Java程序运行机制 5 1.3.1 高级语言的运行机制 6...

    Java初学者入门教学

    A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...

    Java语言的科学与艺术(国外计算机科学经典教材)

     3.2 常量与变量  3.3 运算符和操作数  3.4 赋值语句  3.5 布尔表达式  3.6 设计改变  3.7 小结  3.8 复习题  3.9 编程练习 第4章 语句形式  4.1 Java的语句类型  4.2 控制语句和问题解决  4.3 if 语句 ...

    java联想(中文)

    A.1.3 传递和使用Java对象 A.1.4 JNI和Java违例 A.1.5 JNI和线程处理 A.1.6 使用现成代码 A.2 微软的解决方案 A.3 J/Direct A.3.1 @dll.import引导命令 A.3.2 com.ms.win32包 A.3.3 汇集 A.3.4 编写回调函数 A.3.5 ...

    Java语言的科学与艺术 斯坦福大学经典教材

    2.3 两数相加的程序 2.4 编程习语和模式 2.5 类和对象 2.6 图形程序 2.7 小结 2.8 复习题 2.9 编程练习 第3章 表达式 3.1 原始数据类型 3.2 常量与变量 3.3 运算符和操作数 3.4 赋值语句 3.5 布尔表达式 3.6 设计...

    java的传值与传引用详解

     Java 中,改变参数的值有两种情况,第一种,使用赋值号“=”直接进行赋值使其改变,如例 1 和例 4;第二种,对于某些对象的引用,通过一定途径对其成员数据进行改变,如例 3。对于第一种情况,其改变不会影响到...

Global site tag (gtag.js) - Google Analytics