软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
移动开发 架构设计 编程语言 Web前端 互联网
开发杂谈 系统运维 研发管理 数据库 云计算 Android开发资料
  软件世界网 -> 开发杂谈 -> Java中对象与引用 -> 正文阅读

[开发杂谈]Java中对象与引用


 初学Java 时,在很长一段时间里,总觉得基本概念很模糊。后来才知道,在许多Java 书中,把对象和对象的引用混为一谈。
    如果分不清对象与对象引用,那实在没法很好地理解下面的面向对象技术,把自己的一点认识写下来,或许能让初学Java 的朋友们少走一点弯路。        
    为便于说明,我们先定义一个简单的类:      
 class student{  
  int name;  
  int age;  
  int sex;  
}   
    有了这个类( 模板) ,就可以用它来创建对象:student stu1 = new student();
    通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作。
    1) 右边的"new student" ,是以student 类为模板,在堆空间里创建一个student 类的对象( 也简称为student 对象) 。
    2) 末尾的() 意味着,在对象创建后,立即调用student 类的构造函数,对刚生成的对象进行初始化。
构造函数是肯定有的。如果你没写,Java 会给你补上一个默认的构造函数。
    3) 左边的"student stu1" 创建了一个student 类引用变量。所谓student 类引用,就是以后可以用来指向某个
student 对象的对象引用,它指向的是某个student 对象的内存地址( 有点C 语言中指针的味道) 。
    4)"=" 操作符使对象引用指向刚创建的那个student 对象。
    我们可以把这条语句拆成两部分:student stu1; stu1 = new student(); 效果是一样的。
    这样写,就比较清楚了,有两个实体:一是对象引用变量(stu1) ,在Sun 公司的实现中, 对象的引用是一个句柄, 其中包含一对指针: 一个指针指向该对象的方法表,一个指向该对象的数据;另一个是对象本身( 就是new 出来的那个对象) 。
    在堆空间里创建的实体,与在数据段以及栈空间里创建的实体不同。尽管它们也是确确实实存在的实体, 但是,我们看不见,也摸不着。不仅如此,我们仔细研究一下第二句,想想刚刚创建的student 对象叫什么名字?
    有人说,它叫"student" 。不对,"student" 是类( 对象的创建模板) 的名字。一个student 类可以据此创建 出无数个对象,这些对象不可能全叫"student" 。对象连名都没有,没法直接访问它。我们只能通过 对象引用来间接访问对象。
    为了形象地说明对象、对象引用及它们之间的关系,可以做一个或许不很妥当的比喻:
    对象好比是一只没有线的风筝,引用变量是一根线,可以用来系风筝。如果只执行了第一条语句, 还没执行第二条,此时创建的引用变量stu1 还没指向任何一个对象,它的值是null ,引用变量可以 指向某个对象,或者为null 。这时stu1 是一根线,一根还没有系上任何一个风筝的线。
    执行了第二句后,一只新风筝做出来了,并被系在stu1 这根线上。我们抓住这根线,就等于抓住了那只风筝。
    再来一句:student stu2; 就又做了一根线,还没系上风筝。如果再加一句:stu2=stu1; 系上风筝了。
    这里,发生了复制行为。但是,要说明的是,对象本身并没有被复制,被复制的只是对象引用。
    结果是,stu2 也指向了stu1 所指向的对象,也就是两根线系的是同一只风筝。
    如果用下句再创建一个对象:stu2=new student(); 则引用变量stu2 改指向第二个对象。
    从以上叙述再推演下去,我们可以获得以下结论:
    (1) 一个对象引用可以指向0 个或1 个对象( 一根线可以不系风筝,也可以系一个风筝) ,而且可以改指;
    (2) 一个对象可以有N 个引用指向它( 可以有N 条线系同一个风筝) 。
如果有下面语句:stu1=stu2;
    按上面的推断,stu1 也指向了第二个对象。这个没问题。问题是第一个对象呢?没有一条线系住它,它飞了。
    很多书里说,它被Java 的垃圾回收机制回收了,这不确切,准确地说,它已成为Java 垃圾回收机制的处理对象。
    至于什么时候真正被回收,那要看垃圾回收机制的心情了。由此看来,new student(); 该语句应该不合法吧,
    至少是没用的吧?不对,它是合法的,而且可用的。譬如,如果我们仅仅为了打印而生成一个对象, 就不需要用引用变量来系住它。最常见的就是打印字符System.out.println("I am Java!"); 字符串对象"I am Java!" 在打印后即被丢弃,有人把这种对象称之为临时对象。
 
 
java中的构造函数
原则:
1.构造方法不能声明返回类型,不能被static、final、synchronized、abstract、native修饰。
2.当某个类中没有自定义的构造方法时,编译器会自动为你产生一个缺省的构造方法,这是一个不带参数且没有任何代码的构造方法;但是一旦你为你的类定义了一个构造方法,不管是否带参数,那么编译器将不会再为你产生缺省的构造方法。
3.父类的构造方法不能被子类继承。子类不能直接通过方法名调用父类的一个构造方法,而是要通过super关键字调用父类的一个构造方法,super语句必须位于子类构造方法的第一行。
4.当你试图调用某个类的某一构造方法(暂定名为a方法)来产生该类的一个实例时,将首先需要调用其父类的构造方法,此时有两种情况:(1)a方法中显示地用super关键字调用了父类的某一构造方法(是否带参都行)(注意此时super句必需出现在a方法的第一行);(2)a方法中没有显示地用super关键字调用了父类的某一构造方法,此时编译器在编译子类时会a方法中的第一行加上super();语句。
5.当一个类有几个构造方法时如果想在一个构造方法(暂定名为a)中调用另一个构造方法(暂定名为b),需要使用this关键字而不是用方法名直接调用且this句必需放在第一行;在这种情况下,如果通过this关键字调用的构造方法b中显示地调用了父类的某一构造方法时,编译器不会再在a方法中添加super();来调用父类的缺省构造方法。
 

也谈Java值传递-到底传递了什么?

java里面只有值传递,这是不变的真理,不过由于对象类型的特殊性,有些人还是会疑惑 值传递?还是 引用传递?
可能主要是这句话造成的: 在Java中方法参数的传递,对象是传递引用,基本数据类型是传递值。
如果java里面只有值传递,为何又要说对象是 引用传递?
对于 基本数据类型 是值传递,相信没有人会有疑惑。那对象到底传递了什么?
其实这源于JAVA在解释其变量类型时的一个混淆:JAVA里面只有8种基本数据类型和对象类型
于是便有了 基本数据类型是传递值,对象是传递引用
其实如果把对象类型也解释成一种基本数据类型 ,那就不会出现 对象是传递引用 这句话让人疑惑的话了
下文将 对象类型 看成一种新的基本类型, 姑且称之为 olong (object long),即 所有对象变量 都是 olong,虽然在java书写时可以写成具体的对象类型,如 Long a; 但其传递实质是  olong a;
让我们来重新认识 olong 吧:
赋值:

long a = 1234;

olong oa = new Long(1234); //Long oa = new Long(1234);

传递:

long b = a;
olong ob =oa;  //Long ob = oa;
 
改变:
b = 4321;
ob = new Long(4321); //ob = new Long(4321);

改变了什么?:

System.out.println(a); //输出 1234
System.out.println(b); //输出 4321
System.out.println(oa.longValue()); //输出 1234
System.out.println(ob.longValue()); //输出 4321

到底传递了什么:

long:
long a = 1234; //a的值1234
long b = a;//值传递 b的值1234;a的值1234
b = 4321;//b的值被改变为4321;但a不受影响,依然是1234

olong:

long类型的变量保存和传递的是其指代的基本类型的值,那么olong呢?
可以认为olong类型的变量保存和传递的是一个指向具体对象的内存地址,
olong oa = new Long(1234);//假设new Long生成的对象的地址为0001,则oa的值为0001
olong ob =oa; //值传递,ob的值0001;oa的值0001
ob = new Long(4321);//ob的值被赋予一个新的对象的地址,假设为0002,但oa的值不受影响,依然为0001
因此olong类型的赋值结果与long类型的表现一致,也是值传递

为什么对象是传递引用?

其实这句话也不错,因为olong变量本身就是一个引用,引用了一个对象(的内存地址)
但其实质是 值传递!只不过因为 olong 的值 还有一个 别名 叫做 引用,所以就被叫做了一个让人迷惑的新词:引用传递!

总结:

olong的引入只是为了方便解释Java对象的值传递,说明在参数传递过程中,对象变量的传递和基本变量的传递是没有本质区别的,所以,在Java中,没有 引用传递,只有值传递!






再啰嗦下    
如下表达式:
  A a1 = new A();
它代表A是类,a1是引用,a1不是对象,new A()才是对象,a1引用指向new A()这个对象。
在JAVA里,“=”不能被看成是一个赋值语句,它不是在把一个对象赋给另外一个对象,它的执行过程实质上是将右边对象的地址传给了左边的引用,使得左边的引用指向了右边的对象。JAVA表面上看起来没有指针,但它的引用其实质就是一个指针,引用里面存放的并不是对象,而是该对象的地址,使得该引用指向了对象。在JAVA里,“=”语句不应该被翻译成赋值语句,因为它所执行的确实不是一个赋值的过程,而是一个传地址的过程,被译成赋值语句会造成很多误解,译得不准确。
再如:
A a2;
它代表A是类,a2是引用,a2不是对象,a2所指向的对象为空null;
再如:
a2 = a1;
它代表,a2是引用,a1也是引用,a1所指向的对象的地址传给了a2(传址),使得a2和a1指向了同一对象。
综上所述,可以简单的记为,在初始化时,“=”语句左边的是引用,右边new出来的是对象。
在后面的左右都是引用的“=”语句时,左右的引用同时指向了右边引用所指向的对象。
再所谓实例,其实就是对象的同义词。

......显示全文...
    点击查看全文


上一篇文章      下一篇文章      查看所有文章
2016-04-02 21:01:37  
开发杂谈 最新文章
BloomFilter
大学四年编程之历程
内核分析
造人论坛——意识的本质和一个人工脑模型
OFDM信号[matlab描述]
人类还会进化吗?
HDUACM1035RobotMotion简单模拟题
树、二叉树(二)
iisphpweb.config处理404,500等,跳转友好
DatabaseAsaFortress
360图书馆 软件开发资料 文字转语音 购物精选 软件下载 美食菜谱 新闻资讯 电影视频 小游戏 Chinese Culture 股票 租车
生肖星座 三丰软件 视频 开发 短信 中国文化 网文精选 搜图网 美图 阅读网 多播 租车 短信 看图 日历 万年历 2018年1日历
2018-1-20 7:30:11
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --