Java知识点梳理( 六 )


20、内部类内部类指的是在一个类的内部所定义的类,类名不需要和源文件名相同 。在Java中,内部类是一个编译时的概念,一旦编译成功,内部类和外部类就会成为两个完全不同的类,共有四种类型:
(1)成员内部类:成员内部类是外围类的一个成员,是依附于外围类的,所以,只有先创建了外围类对象才能够创建内部类对象 。也正是由于这个原因,成员内部类也不能含有 static 的变量和方法;
(2)静态内部类:静态内部类,就是修饰为static的内部类,该内部类对象不依赖于外部类对象,就是说我们可以直接创建内部类对象,但其只可以直接访问外部类的所有静态成员和静态方法;
(3)局部内部类:局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法和属性中被使用,出了该方法和属性就会失效;
(4)匿名内部类:定义匿名内部类的前提是,内部类必须要继承一个类或者实现接口,格式为 new 父类或者接口(){定义子类的内容(如函数等)} 。也就是说,匿名内部类最终提供给我们的是一个匿名子类的对象 。
20.1内部类的作用(1)间接实现多重继承,例如:

Java知识点梳理

文章插图
 
(2)内部类还可以很好的实现隐藏(一般非内部类,是不允许有private与protected权限的),但内部类可以 。
 
21、equals,hashCode,==(1)== 用于判断两个对象是否为同一个对象或者两基本类型的值是否相等;
(2)equals 用于判断两个对象内容是否相同;
(3)hashCode是一个对象的消息摘要函数,一种压缩映射,其一般与equals()方法同时重写;若不重写hashCode方法,默认使用Object类的hashCode方法,该方法是一个本地方法,由 Object 类定义的 hashCode 方法会针对不同的对象返回不同的整数 。
21.1 equals与hashCode的区别(1)一般来讲,equals 这个方法是给用户调用的,而 hashcode 方法一般用户不会去调用;
(2)当一个对象类型作为集合对象的元素时,那么这个对象应该拥有自己的equals()和hashCode()设计,而且要遵守前面所说的几个原则 。
21.2 在HashMap中使用可变对象作为Key带来的问题 
HashMap用Key的哈希值来存储和查找键值对,如果HashMap Key的哈希值在存储键值对后发生改变,那么Map可能再也查找不到这个Entry了 。也就是说,在HashMap中可变对象作为Key会造成数据丢失 。因此,
(1)在HashMap中尽量使用不可变对象作为Key,比如,使用String、Integer等不可变类型用作Key是非常明智的或者使用自己定义的不可变类 。
(2)如果可变对象在HashMap中被用作键,那就要小心在改变对象状态的时候,不要改变它的哈希值了,例如,可以只根据对象的标识属性生成HashCode 。
Java知识点梳理

文章插图
 
21.3 重新equals但不重写HashCode会出现的问题在使用Set时,若向其加入两个相同(equals返回为true)的对象,由于hashCode函数没有进行重写,那么这两个对象的hashCode值必然不同,它们很有可能被分散到不同的桶中,容易造成重复对象
的存在 。
22、什么是不可变对象一个不可变对象应该满足以下几个条件:
(1)基本类型变量的值不可变;
(2)引用类型变量不能指向其他对象;
(3)引用类型所指向的对象的状态不可变;
(4)除了构造函数之外,不应该有其它任何函数(至少是任何public函数)修改任何成员变量;
(5)任何使成员变量获得新值的函数都应该将新的值保存在新的对象中,而保持原来的对象不被修改 。
23、Java的序列化/反序列化机制使用Serializable序列化/反序列化 。将实现了Serializable接口的对象转换成一个字节序列,并能够在以后将这个字节序列完全恢复为原来的对象,序列化可以弥补不同操作系统之间的差异 。其中,需要注意以下几点:
(1)需要序列化的对象必须实现Serializable接口;
(2)只有非静态字段和非transient字段进行序列化,与字段的可见性无关;
(3)序列化/反序列化的实质上操纵的是一个对象图;
Java知识点梳理

文章插图
 
 此外,Java中常用到的序列化方法还有 XML、JSON 等,此不赘述 。
24、Path及ClassPath环境变量(1)Path系统用来指定可执行文件的完整路径 。当在CMD中执行命令时,如果执行的可执行文件不在当前目录下,那么系统就会依次搜索PATH中设置的路径 。如果在PATH中设置了JDK的安装目录(如在PATH中添加如下的路径——D:ProgramFilesJavajdk1.8.0bin;D:ProgramFilesJavajdk1.8.0jrebin;),那么就可以在CMD中直接使用java、javac等命令,而不必在CMD中切换到JDK的安装目录下运行该命令 。


推荐阅读