一、数据类型
Java中有基本数据类型和对象数据类型
基本数据类型:(只有值,没有ID)与其他值无法区分,在栈中分配内存
对象数据类型:既有ID,也有值,一些可变,一些不可变,在堆中分配内存
对象类型中形成层次结构,可以继承,可以实现接口
二、静态/动态类型检查
静态(可不运行程序,在编译阶段进行检查)
动态(可运行程序,在运行阶段进行检查)
进行类型转化的时候一定要注意
动态类型检查>静态>无检查
静态类型检查:可在编译阶段发现错误,避免了将错误带入到运行阶段,可提高程序正确性,健壮性。
静态类型检查会检查出以下的错误。(语法错误,类名/函数名错误,参数数目错误,参数类型错误,返回值类型错误)。但是与变量值相关的检测不出来(比如除0)
动态类型检查可以检查出以下的错误(非法的参数值(除0),非法的返回值,越界问题,空指针)
静态类型检查与动态类型检查最大的区别就是
静态检查是关于“类型”的检查,不考虑值,而动态检查是关于“值”的检查
三、可变性与不可变性
加上final , final A,如果A是不可变类型的,那么它就什么也不能变了,如果 final A,A是可变类型的,那么引用不能变,里面的值可以变。
如果编译器无法确定final变量不会改变,就提示错误,这也是静态类型检查的一部分。
final特性:final类无法派生子类;final变量无法改变值/引用;final方法无法被子类重写
不变对象:一旦被创建,始终指向同一个值/引用
可变对象:拥有方法可以修改自己的值/引用
字符串类型就是一个很好的例子,String是immutable的,而Stringbuilder则是mutable的。
对于多个引用来说,两者是有区别的。不可变性会维持原来的什么都不变,可变类型原来指向的和现在指向的对象是同一个,都会发生改变
可变类型和不可变类型,两者各有优缺点
使用mutable类型的,可能会有影响,可以使用defencecopy或设置private final来避免
不能直接返回引用,要用defence copy 。 new一个新的用来返回。
解决办法如下:
我们不能对可变类属性进行操作,要用set/get方法,而且还不能直接返回可变数据类型。
四、Snapshot Diagram
这个之前前几章的复习中给过一个连接,讲的非常清楚,不再赘述,粘上ppt
右边的那个题注意到了中间,那个时候s1是abcd,但s1已经不是list《0》了
就像下面的答案
五、复杂数据类型
数组,一旦创建,就不可以改变它的长度。
列表,长度可以动态改变,List是一个接口,有arraylist和linkedlist两个具体类
ArrayList详解
LinkedList详解
set集合:一个抽象接口,里面的元素是无序的,而且是不能重复的
map图
迭代器
Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。
Iterator 是 Java 迭代器最简单的实现,ListIterator 是 Collection API 中的接口, 它扩展了 Iterator 接口。
迭代器 it 的两个基本操作是 next 、hasNext 和 remove。
调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。
调用 it.hasNext() 用于检测集合中是否还有元素。
调用 it.remove() 将迭代器返回的元素删除。
迭代器的具体实现(把握住里面的index list 和next中的局部元素element)
迭代中需要注意的地方
Iterator iter = subjects.iterator
while(iter.hasext())
{
String subject = iter.next();
if(subject.startwith(“6.”))
{
iter.remove();
}
}
六、有用的不可变数据类型
基本类型和其封装对象类型都是不可变的。大多数集合类型是可变的,但是我们可用使用collention中的方法把M->IM。
但这中不变性只能在运行阶段活的,编译阶段无法进行检查。
/*
Collections.unmodifiableList()接受一个(可变的)List,并将其包装为一个看起来像List的对象,但其mutators是禁用的set(), add(), remove()等抛出异常。因此,您可以使用mutators构造一个列表,然后将其封装在不可修改的包装器中(并扔掉对原始可变列表的引用,从而获得一个不可变列表。
*/