软件世界网 购物 网址 三丰软件 | 小说 美女秀 图库大全 游戏 笑话 | 下载 开发知识库 新闻 开发 图片素材
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
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
生肖星座解梦 人民的名义 人民的名义在线看 三沣玩客 拍拍 视频 开发 Android开发 站长 古典小说 网文精选 搜图网 天下美图
中国文化英文 多播视频 装修知识库
2017-7-20 20:37:37
多播视频美女直播
↓电视,电影,美女直播,迅雷资源↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  软件世界网 --