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.父类的构造方法不能被子类继承。
子类不能直接通过方法名调用父类的一个构造方法。而是要通过superkeyword调用父类的一个构造方法,super语句必须位于子类构造方法的第一行。
4.当你试图调用某个类的某一构造方法(暂定名为a方法)来产生该类的一个实例时,将首先须要调用其父类的构造方法,此时有两种情况:(1)a方法中显示地用superkeyword调用了父类的某一构造方法(是否带參都行)(注意此时super句必需出如今a方法的第一行)。(2)a方法中没有显示地用superkeyword调用了父类的某一构造方法。此时编译器在编译子类时会a方法中的第一行加上super();语句。
5.当一个类有几个构造方法时假设想在一个构造方法(暂定名为a)中调用还有一个构造方法(暂定名为b),须要使用thiskeyword而不是用方法名直接调用且this句必需放在第一行;在这样的情况下。假设通过thiskeyword调用的构造方法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出来的是对象。
在后面的左右都是引用的“=”语句时,左右的引用同一时候指向了右边引用所指向的对象。
再所谓实例,事实上就是对象的同义词。
Java中对象与引用的更多相关文章
- Java中对象和引用的理解
偶然想起Java中对象和引用的基本概念,为了加深下对此的理解和认识,特地整理一下相关的知识点,通过具体实例从两者的概念和区别两方面去更形象的认识理解,再去记忆. 一.对象和引用的概念: 在Java中万 ...
- 详解Java中对象的软、弱和虚引用的区别
对于大部分的对象而言,程序里会有一个引用变量来引用该对象,这是最常见的引用方法.除此之外,java.lang.ref包下还提供了3个类:SoftReference.WeakReference和Phan ...
- Java中对象、对象引用、堆、栈、值传递以及引用传递的详解
Java中对象.对象引用.堆.栈.值传递以及引用传递的详解 1.对象和对象引用的差别: (1).对象: 万物皆对象.对象是类的实例. 在Java中new是用来在堆上创建对象用的. 一个对象能够被多个引 ...
- Java中四种引用:强、软、弱、虚引用
这篇文章非常棒:http://alinazh.blog.51cto.com/5459270/1276173 Java中四种引用:强.软.弱.虚引用 1.1.强引用当我们使用new 这个关键字创建对象时 ...
- 理解Java中的弱引用(Weak Reference)
本篇文章尝试从What.Why.How这三个角度来探索Java中的弱引用,理解Java中弱引用的定义.基本使用场景和使用方法.由于个人水平有限,叙述中难免存在不准确或是不清晰的地方,希望大家可以指出, ...
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- Java中对象的生与灭- 核心篇
前言 大家好啊,我是汤圆,今天给大家带来的是<Java中对象的生与灭- 核心篇>,希望对大家有帮助,谢谢 文章纯属原创,个人总结难免有差错,如果有,麻烦在评论区回复或后台私信,谢啦 简介 ...
- 你真的了解JAVA中对象和类、this、super和static关键字吗
作者:小牛呼噜噜 | https://xiaoniuhululu.com 计算机内功.JAVA底层.面试相关资料等更多精彩文章在公众号「小牛呼噜噜 」 目录 Java对象究竟是什么? 创建对象的过程 ...
- java 中对象比较大小
java 中对象比较大小 java 中对象比较大小有两种方法 1:实现Comparable 接口 的 public int compareTo(T o) 方法: 2:实现Comparator 接口 的 ...
随机推荐
- Google的网站性能优化最佳实践
网站性能最佳实践 当描述一个web页面的页面速度,评价的一致性遵循许多不同的规则.这些规则是任何阶段的web开发可以应用的前端最佳实践.这个文档的每个规则都陈述于此,无论你是否运行页面测速工具-- ...
- P1796 汤姆斯的天堂梦_NOI导刊2010提高(05)
题目描述 汤姆斯生活在一个等级为0的星球上.那里的环境极其恶劣,每天12小时的工作和成堆的垃圾让人忍无可忍.他向往着等级为N的星球上天堂般的生活. 有一些航班将人从低等级的星球送上高一级的星球,有时需 ...
- 关于jquery的clone()和javascript的cloneNode()
区别: jquery的clone( ),如果是true就是深克隆,把事件都会克隆过去:如果是false,则仅仅克隆的是结构: javascript的cloneNode( ),如果是true,会将子节点 ...
- 【Oracle】服务器端监听配置
一.静态监听 创建端口为1521的监听,静态注册,本机ip:192.168.10.2 [oracle@localhost ~]$ vi /u01/app/oracle/product/11.2.0/d ...
- 45.4.7 序列:USER_SEQUENCES(SEQ)
45.4.7 序列:USER_SEQUENCES(SEQ) 要显示序列的属性,可以查询USER_SEQUENCES 数据字典视图.该视图也能用公有同义词SEQ 进行查询.USER_SEQUENCES ...
- 【sqli-labs】 less42 POST -Error based -String -Stacked(POST型基于错误的堆叠查询字符型注入)
Forgot your password? New User click here? 看源码,可以发现和less 24不同的一点在于password字段没有进行转义处理 那就对password字段进行 ...
- XML文件读取加上 Ajax请求
#region XML文件处理 XmlDocument doc = new XmlDocument(); XmlReaderSettings settings = new XmlReaderSetti ...
- DFS-BFS深度优选遍历和广度优先遍历
https://www.jianshu.com/p/b086986969e6 DFS--需要借助stack实现 stack.push stack.pop BFS--需要借助队列queue stack- ...
- python PIL图像处理-框选
框选图中位置 代码 from PIL import Image,ImageDraw,ImageFont,ImageFilter import random #--------------------- ...
- php第十一节课
增删改查 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...