关键字 null 总结


作用:

1.默认给变量赋值。

引用类型的成员变量自动初始化时候赋值为null。

2.判断一个类型是否为空。

用“==”符号来判断。

3.释放内存(功能受限)

如果堆中一个对象仅被一个引用变量引用,那么将这个引用变量赋值为null就是这个对象在堆中的空间就不被引用了,JVM的GC会去自主回收。

功能受限原因是现实中很难保证说堆中这个对象就一定仅仅被这一个引用变量所引用(指向)

4.变量在try catch finally语句块中的try中赋值而且下面代码有进行进一步操作的需要先赋值成null。

Connection conn = null;
 try {
 conn = DriverManager.getConnection("url", "user", "password");
 } catch (SQLException e) {
 e.printStackTrace();
 }
 String catalog = conn.getCatalog();

注意:

1.八种基本数据类型是不能够赋值null的。

int a = null;会直接提示错误。

2.null并不是一个Object以及Object子类任何对象的实例。

也就是说 一个=null的引用变量 instanceof运算符得到的结果永远是false。

另外“a instanceof A”操作首先‘A’必须是个类,其次 ‘a’是"A1 a"这样声明的‘A1 a’

3.null在容器中的注意。

List:允许重复元素,可以加入任意多个null。

Set:不允许重复元素,最多可以加入一个null。

Map:Map的key最多可以加入一个null,value字段没有限制。

数组:引用类型数组,不给定初始值,则所有的元素值为null。

基本类型数组,定义后,如果不给定初始值,则java运行时会自动给定默认值。

核心研究:

测试类代码:

public class Test1 {
 public static void helloStatic(){
 System.out.println("Hello Static ...");
 }
 public void helloDynamic(){
 System.out.println("Hello Dynamic ...");
 }
 
 public static void main(String[] args) {
 Test1 t1 = null;
 t1.helloStatic();
 t1.helloDynamic();
 }
 }

精髓:

1.null和Object的纠缠

a.一个引用变量为null(如“Test1 t1 = null;”)当通过instanceof运算符运算(如“t1 instanceof Object”)返回false。

b.Test1 t1 = null; t1非对象但是却可以调用Test1的静态方法helloStatic()。当调用非静态方法时会报错空指针。

c.对于引用类型变量并不赋值null(如“Test1 t1;”)让这个变量调用类的方法那么编译时就报错“The local variable

t1 may not have been initialized”即变量(对象)t1未初始化。

d.回忆一下内存分析可以知道Test1 t1;仅仅是将栈中新建一个t1变量,

Test1 t1=new Test1();是在栈中新建一个t1变量而且在堆中开辟一块空间新建对象,并将t1指向这个对象

对比上面的结果可以推测出:null也是一种特殊的对象

猜想:

对于Test3 extends Test2 extends Test 然后 ToXML是没有和他们三个有继承关系的类 四个类都是Object子类

代码如下:

Test3 t3=null;
 Test2 t2=null;
 Object o=null;
 ToXML txl=null;
 System.out.println(t2==t3); //true
 System.out.println(o==t3); //true
 System.out.println(txl==o); //true
 System.out.println(txl==t2); //编译时报错Incompatible operand types ToXML and Test2

由上可知在对引用类型的变量进行'=='判断的时候编译器是先判断这两个引用类型变量声明时是否一个家族的

如果不是一个家族的就直接报错了。

由此可知引用类型的变量被声明的时候就已经携带了引用类型类的信息了

因而可以猜测声明为null的变量拥有调用其引用类型类(及其父类)的静态方法的权限是在声明时赋予的。

猜测null在jvm中是存在一个小空间,Test3 t3=null是将这个小空间的地址放进赋予t3这个变量(指针)。

如果成立那么可以解释通任何为null的变量打印都是‘null’调用非静态方法的时候都抛空指针异常

如果成立那么null可以理解为一个‘对象’(当然不是,真真意义上的对象),或者说Object的‘父类’。--①

①仅仅是为了能够更形象的理解而做的比喻,null不是对象

根据实验猜测:instanceof 在比较的时候会看看前面的是否为null是的话直接返回false

instanceof 在比较前会先看看后面的是否为一个类,如果是个基本类型根本就编译不通过