前言:关键字包含 #指针,java 引用,空指针,地址访问,引用类型,在 Java 编程语言中,程序员不需要担心程序的内存使用。Java 语言的自动垃圾收集器会不时地清理那些变成垃圾的对象。
如果垃圾收集没有发生,垃圾对象将保留一个内存位置,直到程序执行结束。下面讲讲之前会怎么涉及引用的知识。
Java 中引用因为存储的就是地址,所以实质上引用就是指针的另一种形式,只不过这种形式是安全形式的指针,因为引用是处于被动的存储地址的一个存在,是受控的,所以是安全的。所以 java 使用引用来代替了指针,他指向收引用的实体。
安全性体现:
会检查空指针引用
不存在使用指针运算*(p++)
不能访问没有引用到的地址
自动回收内存
C 语言与 Java 指针的关系
传地址与对象
引用类型:引用本身就相当于指针,所以可以用来修改对象的属性,调用对象的方法两大功能。
基本类型:
指针运算可以用数组代替,*(p+5)可以用 args[5]代替
函数指针是在 Java 中使用接口,Lambda 表达式,可以进行求积分,线程,回调函数,事件处理。 指向结点的指针指的是 Java 中对象的引用 Node next,实现链表中的结点,树结构中的结点。
使用 JNI 本地接口(Java Native Interface),他允许 Java 代码和其他语言的代码进行交互。
相等还是不相等区分:
基本类型是值相等,引用类型是引用的对象相同。
基本类型使用要注意的地方:
数值类型:转换后比较相等
浮点数:不要直接使用==
注意 Boolean 类型不能与 int 比较
注意 Bouble.NAN==Double.NAN 结果为 false
枚举类型:
内部进行了唯一实例化,所以可以直接判断
引用对象类型:
关注的是引用是否一样
判断内容一样,使用 equals 方法失效
所以要重新写 equals 的同时,记得修改 hashCode()方法
String 对象:
判断相等,注意一定不要用==,使用 equals 方法
注意字符串常量会进行内部化相等处理,唯一可以使用==
代码分析,可以看到得到结果是 false,因为对象是两个,不是一个对象,所以是 false
Integer i=new Integer(10);
Integer j=new Integer(10);
System.out.println(i==j);
复制代码
下面两个整数是基本类型,并且因为有缓存的存在,m 与 n 都表示同一个地方的数字 10,所以 true。
Integer m=10;
Integer n=10;
System.out.println(m==n)
复制代码
下面两个之间的数字已经超过了 127 整数值,所以不会存在正确的赋值,所以被引用到两个不同的地方,所以两个整数的对象是两个,虽然值相等,但是结果是 false。
Integer p=300;
integer q=300;
System.out.println(q==p);
复制代码
String.intern()方法的需要和工作:
在 Java 中创建字符串时,它会占用堆中的内存。另外,我们知道 String 类是不可变的。因此,无论何时我们使用 new 关键字创建字符串,都会在堆中为相应的字符串分配新的内存,而与数组的内容无关。下面的代码片段得到两个对象的结果为 False,因为不是字符串常量
String str = new String("Welcome to Java");
String str1 = new String("Welcome to Java");
System.out.println(str1 == str);
复制代码
在 Java 中创建对象是一项开销很大的操作。因此,为了节省时间,Java 开发人员提出了字符串常量池(String Constant Pool, SCP)的概念。SCP 是堆内存中的一个区域。它包含唯一的字符串。为了将字符串放入字符串池中,需要调用 intern()方法。在字符串池中创建对象之前,JVM 检查该字符串是否已经存在于池中。如果字符串存在,则返回它的引用。
下面结果前面对象引用不同,所以结果为 Fasle,后面常量引用相同,所以 True。
public class InternExample{
public static void main(String args[]){
String s1=new String("hello");
String s2="hello";
String s3=s1.intern();
System.out.println(s1==s2);
System.out.println(s2==s3);
}}
复制代码