引用
引用(regerence)
一、引用及对象的相关概念:
1.java中没有指针和地址的概念
2.认识对象的一种视角–组织管理数据的一个概念,表现为内存中的一块区域
(对象的大小远大于引用的大小!)
3.java中不允许程序直接接触对象,只能通过引用间接操控对象。(引用是类似于电视遥控器一样的存在,看电视的人只能通过遥控器的操作间接控制电视,看自己想看的频道)也就是可以通过引用可以操作对象
* 引用的优点:
1)安全,因为引用是间接操控对象,所以就接触不到对象,也就对对象造不成伤害,保障了对象的安全性。
2)可控,引用只能只能使用规定范围内的功能。
4.引用不一定非要指定一个对象,但是一定要指定的话一个引用只能指定一个对象,不可指向多个对象(引用指向什么对象也有一定的规定)
5.一个对象可以同时被多个引用指向
6.引用的类型也是有很细的分类的
*Scanner s;
*String str;
*long[] array;
…
7.引用的赋值:
public class 观察引用对象 {
public static void main(String[] args) {
long[] a1 = {1,2,3,4,5 };//a1指向数组对象{1,2,3,4,5}
long[] a2 = a1;//a2作为一个引用指向a1目前引用指向的对象
}//数组类型也属于引用类型的一种
8.引用大小的比较:
1)在引用中没有>和<的比较(也就是说引用中没有大于小于的比较)
2)
String s = ...;
String t = ...;`
s == t ->>true 代表的是s和t目前指向同一个对象(也可能二者目前都为null)
s != t ->>true 代表的是s和t目前不指向同一个对象(二者中有一个为null,一个不是)
9.引用的作用:用来操作对象
二、解引用(Dereference):
1.含义:通过引用,修改或获取该引用指向的对象中的数据
举例如下:
a1.length:通过a1找到a1指向的对象,并获取对象中保存的length的值
a1[0]:通过a1找到a1指向的对象,并获取对象中下标为0的位置元素的值
a1[0]=100:通过a1找到a1指向的对象,修改对象中下标为0的位置的元素的值
2.相关代码举例:
public class 观察引用对象 {
public static void main(String[] args) {
long[] a1 = {1,2,3,4,5 };//a1指向数组对象{1,2,3,4,5}
System.out.println(a1.length);
}
public class 观察引用对象 {
public static void main(String[] args) {
long[] a1 = {1,2,3,4,5 };//a1指向数组对象{1,2,3,4,5}
System.out.println(a1[3]);
}
public class 观察引用对象 {
public static void main(String[] args) {
long[] a1 = {1,2,3,4,5 };//a1指向数组对象{1,2,3,4,5}
long[] a2 = a1;
a1[3] = 57;
System.out.println(Arrays.toString(a1));
}
3.解引用运行异常:
public class 观察引用对象 {
public static void main(String[] args) {
long[] a1 = null;//定义了一个引用,不指向任何对象
long b = a1.length;//通过a1引用.找到a1指向的对象获取对象中length的值
System.out.println(b);//
}
运行结果:
注:进行解引用时(. []),如果引用是null(不指向任何对象)就会空指针异常,通常显示NPE
1)在Java中,null是关于引用类型的特殊字面量
2)“null”的含义:这个引用没有指向任何对象,与C语言中的NULL(空指针)相似,表示一个无效的内存位置,一旦对定义好的null进行读写操作就会出现空指针异常NPE
3)Java中没有规定null和0号地址的内存有任何关联
举例:
String s = null;
//S是String类型的引用,目前没没有指向任何对象
4.解引用比较两个数组:
public class 观察引用对象 {
public static void main(String[] args) {
long[] a1 = {1,2,3};
long[] a2 = {1,2,3};
System.out.println(a1 == a2);
}
运行结果:
a1 a2不指向一个对象
解决方法:使用Array.equals(a1,a2)就可以真正的比较数组的值
代码及运行结果如下:
public class 观察引用对象 {
public static void main(String[] args) {
long[] a1 = {1,2,3};
long[] a2 = {1,2,3};
System.out.println(a1 == a2);
System.out.println(Arrays.equals(a1,a2));
}
三、引用在数组中的应用:
1.一维数组:
long[] a = null;
//定义了long类型的数组,目前不指向任何对象
a = new long[]{1,2,3,4,5 };
//"="右边部分的new是让JVM构造或者实例化出对象(数组对象)
//"="左边部分的a是赋值的过程:引用的赋值操作就是让某个引用指向对象
long[] b = a;
//重新定义一个long类型的数组b,让b引用指向a引用指向的对象
2.二维数组:
long[][] a = null;
//数组的元素类型是:long[](引用类型)
long[][] a = new long[5][];
//定义了一个元素类型是long[]的数组,数组长度是5
a[0][0] = 10;
若在上一段代码中执行该操作会发生什么?
1).通过a(long[][])引用,找到其指向的对象
2).a[0]的到其下标为0的元素(long[]类型的引用),记为e
3).通过e[0],相当于找到了e指向的对象,把其0下标的元素修改为10
结果:由于e = null,无法实现第三步,空指针异常
若想让a[0][0] = 10;成立,至少要让a[0]引用指向一个元素类型为long的数组,代码如下:
a[0] = new long [5];//a[0]目前指向的是long类型的数组
System.out.println(a[0][0]);//0
a[0][0] = 10;
System.out.println(a[0][0]);//10
注:数组类型属于引用类型的一种,数组的元素、长度信息都放在对象(数组对象)中
四、引用中一些琐碎的知识点:
1.变量的默认值–0的变形,根据变量的数据类型决定
数值类型(整型/浮点/字符):0
boolean:false
引用类型:null
2.形参的改变不会影响实参(使用与基本类型和引用类型)
由于引用具备“共享”特征,如果多个引用指向的是一个对象,通过其中一个引用对对象进行修改,通过其他引用可以看到该变化
也就是说Java中形参的改变不会影响实参,和参数的数据类型无关,但是可以利用引用的“共享性”实现在方法中修改数据,让方法外看到
3.引用支持的操作:
赋值:=
相等判断:==
不等判断:!=
通过引用访问对象:.(相当于的)
数组特有的解引用,也是通过引用访问问对象:[]
4.引用可以不关联到对象上,也就是说引用可以独立存在