14.10.30更新:前4章
14.11.05更新:第5章、第6章
14.11.21更新:第7章、第8章
14.12.01更新:第8章1-3节
第15章1-4节
教材《疯狂java讲义》
第1章
Java程序源文件的文件名,必须与pulic类的类名相同,因此,一个Java源文件里最多只能定义一个public类。
如果没有包含public类定义时推荐让源文件的主文件名与类名相同。
Java中所有的关键字全部是小写的。
为了更快的让垃圾回收机制回收那些不再使用的对象,可以将该对象的引用变量设置为null。
第2章
面向过程:谓(主,宾);
面向对象:主.谓(宾)。
面向对象三大特征:
继承:子类继承父类后,直接获得父类的属性和方法;
多态:子类对象可以直接赋给父类变量,但运行时依然表现子类的行为特征;
封装:将对象的实现细节;
两种结构关系:
一般到特殊:继承关系
整体到部分:组装结构,通过一个类里保存另一个对象引用
第3章
3.1
javadoc工具默认只处理以public或protected修饰的类,如果提取private修饰的内容,可以使用时,增加-private选项;
文档注释,/**开始,*/结束;
javadoc -d <directory> Java源文件 生成API文档。
3.2
标示符可以由字母、数字、下划线和$组成,但是数字不能打头。
Java所有的关键字都是大写。
3.3
解释语言中
<X>表示X需要进一步定义或说明;
[X]表示X可以缺省或出现一此
{X}表示X可以出现一次
X | Y表示X和Y互斥
3.4
Java中基本数据类型:boolean\byte\short\int\long\char\float\double;
字符型相当于一种无符号整数类型。
引用类型包括类、接口和数组,还有一种特殊的null类型。
把一个整数值当做long类型来处理,应该在这个整数值后增加L作为后缀。
二进制,0b(B)开头;八进制,0开头;十六进制,0x(X)开头。
二进制的符号位在强制转换中,符号位不会移动(也就是可能出现正、负颠倒)。
Java中默认的浮点类型是double。
Java中提供了3个特殊的浮点数值:正无穷大(POSITIVE_INFINITY)、负无穷大(NEGATIVE_INFINITY)、非数(NaN)。
只有浮点数除以0才能得到特殊数值,整数除以0会出现除以0异常。
3.5
表达式的类型将严格和表达式中最高等级操作数相同的类型。
3.7
求余运算的结果不一定是总是整数,而是得到一个整除的结果后剩下的值就是余数。
++a,表明先加1,再放到表达式中运算。
赋值表达式的值就是右边被赋的值。
逻辑运算符,|和||区别是,|不会短路,短路就是指若一个操作数已作出判断,则不看第二个。
第四章
4.3
do while循环的循环条件后必须有一个分号;
for 可以声明多个变量,这些变量有相同的数据类型;
在for循环里定义的变量,其作用域仅在该循环内有效。
4.4
break 加标签,标签放在外层循环体外,可以结束外层循环。
4.5
不要同时使用静态初始化和动态初始化。
foreach循环迭代数组元素时,并不能改变数组元素的值。
4.6
数组变量赋为null,便于垃圾回收。
Java二维数组,只初始化左边的变量
数组元素是引用类型,初始化时null
只有Java.lang.*的类不需要打包
直接打印地址,得到数组的地址值
arrays中的参数,fromIndex包括,toIndex不包括。
第五章
5.1
类名必须由有意义的的单词连缀而成,首字母大写,单词之间不使用分隔符。
成员变量名、方法名的第一个单词首字母小写,其他的大写。
static修饰的变量和类属于类本身,而不是属于单个实例,static修饰的成员不能使用没有static修饰的成员。
构造器没有返回值。
定义出来的是变量,new 创建实例赋值给变量,变啦ing放在栈内存,实力放在堆内存。
this关键字总是指向调用该方法的对象。最大的作用就是让类中的一个方法,访问该类里的另一个方法或实例变量。this也可以省略。
static修饰的方法不能使用this关键字,所以static修饰的方法不使用static修饰的普通成员。
构造器中必须使用this,this总是引用该构造器正在初始化的对象。
static修饰的变量存放在对内存的永生代。
局部变量,方法中的局部变量、形参、代码块的变量,局部变量前只能用修饰符final,局部变量必须由程序员赋值。
5.2
引用类型的参数传递,一样采用的是值传递,但只复制了引用变量,不复制引用对象所指的对象,所以指向了同一个堆内存地址,所以传递后修改了堆内存的值,所指向对象得到值就发生的改变。
在最后一个形参类型后增加三个点,表明该形参可以接受多个参数值,多个参数值当成数组传入。这个形参只能处于参数列表的最后,大部分时候不推荐重载形参长度可变的方法。
递归一定要向已知方向递归。
5.3
成员变量指的是在类里面定义的变量;局部变量指的是在方法里定义的变量。
成员变量无需显式初始化,局部变量除了形参之外,必须显式初始化,如果方法里的局部变量和成员变量同名,局部变量会覆盖成员变量。
使用成员变量:
描述某个类或某个对象的固有信息的;
一个变量来保存该类或者实例运行的状态信息;
某个类的多个方法之间共享。
5.4
private:类内;default:包;protected:子类访问;public:公共。
外部类只能使用public和default。
Java源文件里有public类则必须和文件名同名,一个Java源文件里只有一个public修饰的类。
成员变量大多数使用private修饰;工具方法使用private修饰。
类里包含大部分方法可能仅希望被其子类重写使用protected修饰。
类的构造器通过使用public修饰。
使用import可以省略写包名;而使用import static可以省略类名。
5.5
在构造器里调用其他构造器,可以使用this构造器,而且必须作为构造器的第一条语句。
5.6
子类的不能获得父类的构造器,但可以调用父类构造器的初始化代码,使用super,必须出现在构造器执行体的第一行。
Java类可以有无限个简介父类,java.lang.Object类是所有类的父类。
子类返回值类型比父类返回值类型更小或相等;子类抛出的异常应比父类方法声明抛出的异常类更小或相等;子类的访问权限应比父类更大或相等。
在子类中调用父类中被覆盖的方法,可以使用super;
private方法无法被子类重写。
super也不能出现在static修饰的方法。
程序创建一个子类对象时,也会给从父类继承得到的所有实例变量分配内存。
当调用子类构造器来初始化子类对象时,父类构造器总会在子类构造器之前执行。
5.7
子类的实例可以当作父类的对象使用。
多态:同一种类型的变量,在执行同一个方法时,表现出多种行为特征。
多态增加了Java语言的灵活性。
Java的引用变量:有两个类型
一个编译时的类型:由声明它的类型来决定。
一个运行时的类型:由该引用变量所指向的对象。
当调用引用变量的方法时,他总是呈现出它的运行时类型的特征。
当调用成员变量时,呈现出的 应用的变量声明时的类型。(对象的实例变量不具备多态性)
在编译阶段,编译器并不清楚引用变量所使用的类型,编译器只知道它编译时候的类型。
引用变量在编译阶段只能调用其编译时类型所具有的方法。
引用类型之间,只能在具有继承关系的两个类型之间转换。
instanceof运算符,前面操作数的编译类型要么与后面的相同,要么有继承关系。
instanceof判断前面的对象是否是后面的类。
5.8
尽量隐藏父类的内部数据;
不要让子类可以随意的访问修改父类的方法;
工具方法:private;外部调用但不重写:final;可以重写但不被其他类:protected;
尽量不要在父类构造器中调用将要被子类重写的方法。
设置成最终类,则可以使用final修饰这个类,并用private修饰所有的构造器。
需要派生新的子类:行
子类需要额外增加属性;增加自己独有的为方式。
组合中通常在新类中使用private修饰被组合的旧类对象。
组合表达“has a”;继承表达”is a“。
5.9
初始化块中有顺序,前面定义的先执行,而且在构造函数之前,无法通过类、对象来调用。
初始化的顺序先执行初始化块或声明实例变量时指定的初始值,再执行方法,具体初始化块和成员变量的顺序根据他们的位置。
有一段初始化处理代码对所有对象相同,且无需接受任何参数,可以把这段代码放到初始化块中。
使用static修饰的初始化块,将在类初始化阶段执行静态初始化块。而且只出现一次。
加载某个类时,总是保证该类的所有父类全部加载并初始化。
总结:
1.定义类
【修饰符】class 类名 extends 父类{
//0~N个 Field定义
//0~N个 方法定义
//0~N个 构造器定义
//初始化块定义
}
当子类继承了父类之后,子类可以从父类获取Field、方法。
子类构造器【总会】调用父类构造器【一次】。
A。没有super,子类默认调用父类无参数的构造器。
B。有super,子类构造器根据super参数列表去调用父类指定的构造器
初始化块的代码,编译之后自动提取,并插入构造器之前。
2.使用类
A。静态Field或方法,直接用类名调用即可。
B。创建实例,通过实例调用Field或方法
第六章
6.1
Java提供了包装类为8中基本类型分别定义了相应的引用类型。
可以把一个基本类型变量直接赋给对应的包装类变量,或者赋给Object变量。
进行自动装箱和自动拆箱必须注意类型匹配。
包装类还可以实现基本类型变量和字符串之间的转换。
最简单把基本类型变量转换为字符串,把基本类型变量和""进行连接运算。
包装类的实例可以与数值类型的值进行比较。
Integer包装类比较,-128~127相等。因为-128~127使用缓存储存。
6.2
输出对象名,实际是输出对象的toString()方法,所有的对象都可以和字符串进行连接运算。
object的toString()方法,返回类名+@+hascode,一般要重写该方法。
重写多数返回该对象令人感兴趣的信息组成的字符串。
引用变量类型,只有指向同一个对象时,==才相等。
常量池中的字符串可以组装,引用变量“组装”之后不同。
多数object的继承类已经重写了equals方法。
6.3
即使某个实例为null,它也可以访问它所属类的类成员。
类成员不能访问非类成员。
单例的创建方法:P174
6.4
final修饰类、方法和变量不可改变。
final修饰类变量,必须静态初始化块|声明变量,给定初始值。
final修饰成员变量,必须非静态初始化块|声明该实例变量|构造器中,制定初始值。
不要初始化之前访问成员变量的值。
final修饰局部变量,在定义时没有指定默认值,可以在后面赋值,但只能一次。
不能对final修饰的形参赋值。
final修饰引用变量,地址不变,对象内容可变。
final修饰在定义时就赋值且在编译时确定就可以相当于一个直接量。
由字符串连接运算,没有访问普通变量,调用方法也是“宏定义”的直接量。
final修饰方法不能重写,但是可以重载。
final修饰类可以有子类。
不可变类方法:P181
经常使用不可变类,创建缓存。
private修饰构造器,将构造器隐藏起来。
6.5
有抽象方法的类只能被定义为抽象类;
抽象方法不能有方法体,而且方法后增加分号;
抽象类不能实例化;
抽象类的构造器不用于创建实例;
继承抽象类必须重写父类所有的抽象方法。
final和abstract永远不能同时出现。
private和abstract不能同时修饰方法。
抽象类作为子类的模板,避免了子类设计的随意性。
父类的普通方法依赖于一个抽象方法,而抽象方法则推迟到子类中。
6.6
借口让规范和实现分离。
接口的成员变量只能是静态变量,方法只能是抽象方法、类方法和默认方法。
接口的所有成员都是public方访问权限。
成员都是 public statci final;方法都是public abstract。
接口中定义默认方法,使用default修饰。
接口支持多继承。
实现通过使用implements关键字,implements必须放在extends之后,实现接口后必须重写所有的抽象方法。
实现接口方法时,必须使用public访问控制修饰符。
面向接口编程:1.简单工厂模式
2.命令模式。
PS: 我感觉的接口,主要就在使用多态里面,接口不能实例化,但是声明的变量可以指向它的子类(实现它的类),在子类中实现抽象方法,这样使得程序可以修改很少内容的代价,实现很多修改的功能。
6.7
内部类可以访问外部类的私有数据;外部类不能访问内部类的实现细节,必须显示穿件非静态内部类对象。
内部类可以使用private、protected、static几个修饰符。
如果没有static修饰的内部类实例,必须寄生在外部类的对象里。
如果有static修饰的内部类,寄生在外部类的本身里。
外部类对象访问非静态内部类成员时,可能非静态普通内部类对象根本不存在。
非静态内部类里不允许定义静态成员。
非静态内部类的构造器必须使用外部类对象来调用。
创建非静态类的子类时,保证让子类构造器可以调用非静态内部类的构造器。
静态内部类不能访问外部类的实例成员。
外部类可以使用静态内部类的类名作为调用者来访问内部类成员。
创建静态内部类对象时无需创建外部类对象。
静态内部类把外部类但做静态内部类的包空间。
匿名内部类不能重复使用;
匿名内部类不能是抽象类;
匿名内部类不能定义构造器,常用的方式是创建某个接口类型的对象,然后必须重写抽象方法。
局部变量被匿名内部类方文,+final。
6.8
Lambada表达式支持将代码块作为方法参数。
可以代替匿名内部类创建对象,由形参列表,箭头,代码块组成。
实际上将会被当成一个“任意类型”的对象。
目标类型必须是只包含一个抽象方法的接口:函数式接口。
lambada只能为函数式接口创建对象。
Lambda表达式的代码块不允许调用接口中定义的默认方法。
6.9
一个类的对象是有限而且固定的。
枚举类不能显示继承其他类,非抽象枚举类不能派生子类,只能使用private修饰,所有实例必须在枚举类的第一行显式列出。
switch表达式可以是任意枚举类型,case表达式中的值直接使用枚举值的名字。
枚举类的实例只能是枚举值,而不是通过new。
建议成员变量都是用private final 修饰,构造器赋初值。
需要每个枚举值在调用方法时表现出不同的行为方式,则可以让每个枚举值分别实现该方法。
抽象枚举类可以派生子类。
6.10
任何java类都可以重写object类的finalize()方法。
6.11
4个访问控制符是互斥的;
abstract和final不能同时使用;
abstract和static不能同时修饰方法,可以同时修饰内部类;
abstract和private不鞥呢同时修饰方法,可以同时修饰内部类;
private和final同时修饰方法没有意义。
小结:
类前面修饰符:public,abstract|final
接口前面修饰符:public
接口成员变量:public static final
接口方法:public abstract
枚举前面:public abstract|final
第七章 基础类库
7.1用户互动
7.1.1运行程序的参数
java java程序名 第一个参数,第二个参数... 可以使用这样的方法调用参数
7.1.2Scanner类
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
system.out.println("sc.next()");}
设置分隔符:useDelimiter(String pattern)方法
7.2系统相关
7.2.1System类
代表当前Java程序的运行平台。
system.identityHashCode()方法可以根据对象地址计算得到HashCode值。
7.2.2Runtime类
代表Java程序的运行环境。
Runtime rt = Runtime.getRuntime();
还可以单独启动一个进程来运行操作系统命令。
7.3常用类
7.3.1Object类
是所有类、数组、枚举类的父类。
7.3.2Objcets类
工具类。
7.3.3String
String是不可变类。
StringBuffer 字符串序列可变的字符串。
StringBuilder和上面类似,但是高效但是没有实现线程安全。
7.3.4Math
无法创建Math类对象,所有方法是类方法。
7.3.5Random
如果两个对象的种子相同,而且方法的调用顺序也相同,就会产生相同的数字序列。
7.3.6BigDecimal
建议优先使用基于String的构造器
7.4时间类
Calendar calendar = Calendar.getInstance();
set()方法有延迟修改的特性。
7.5正则表达式
7.6国际化与格式化
思路是将程序中的标签、提示等信息放在资源文件中,程序支持哪些国家、语言环境就对应提供相应的资源文件,资源文件是键值对。
ResourceBundle.getBundle(String baseName,Locale local);
使用NumberFormat格式化数字,使用SimpleDataForamt格式化日期。
7.6JDK1.8新增的日期格式化器
使用DateTimeFormatter完成
第八章 集合
8.1概述
Set——无序、不可重复
List——有序、重复
Map——映射关系
Queue——队列集合
集合只能保存对象。
8.2集合遍历
8.2.1
Collection 接口是List Set Queue的父接口,常用add,remove等方法。
使用forEach方法,里面Conmsumer对象进行遍历。
8.2.2
创建Iteratior对象依附Collection对象进行迭代。
8.2.3
使用forEachRemaining进行遍历。
8.2.4
forEach循环将集合看做类似数组。
8.2.5
使用removeIf方法进行筛选,里面Predicate对象相当于一个判断式。
8.2.6
Stream提供了大量的聚集操作。
中间方法,允许流保持打开状态;末端方法,该流将被消耗且不能再使用。
8.3Set集合
8.3.1HashSet
判断相等通过equals()方法比较相等,而且两个对象的hashCode方法也相等。
重写equals和hashcode方法时,保证equals返回true时,他们的hashcode返回值也相等。
尽量不修改集合元素中参与计算hashcode和equals的实例变量。
8.3.2LinkedHashSet
使用链表维护元素的次序,将会按元素的田间顺序访问集合了里的元素。
输出时,元素的顺序总是和添加顺序一致。
8.3.3TreeSet
默认处于自然排序,按照大小升序排列。
向TreeSet中添加的英爱是同一类的对象。
8.3.4EnumSet
EnumSet中的所有元素都必须是指定枚举类的枚举值。
8.3.5Set比较
都是线程不安全的。
8.4List集合
8.4.1List接口
List判断两个对象相等只要通过equals()返回true即可。
set方法不会改变List集合的长度。
8.4.2ArrayList
封装了一个允许再分配的Object[]数组。
8.4.3固定长度List
Arrays.ArrayList是一个固定长度的List集合。
8.5Queue集合
模拟队列的数据结构。
8.5.1PriorityQueue
保存队列元素的顺序并不是按加入队列的顺序。
8.5.2Deque和ArrayDeque
推荐使用ArrayDeque来避免使用栈。
ArrayDeque可以作为栈也可以作为队列。
8.5.3LinkedList
LinkedList可以作为List,双端队列还有栈使用。
8.5.4线性表分析
遍历:ArrayList使用随机访问。
LinkedList使用迭代器。
经常插入,使用Linkedlist,经常重新分配大小,使用ArrayList。
8.6Map集合
Map的Key不重复,类似于Set。
如果新的value覆盖了原有的value,该方法返回被覆盖的value。
8.6.2Hashmap
类似HashSet,盘等条件,key通过equals()方法,而且hashCode值也相等。
判断containsValue方法则要通过equals()方法比较
不适用可变对象作为key.
8.6.3LinkedHashMap
类似LinkedHashSet。
8.6.4TreeMap
类似TreeSet。
8.7Collections
工具类提供了大量方法对集合元素进行排序,查询和修改操作,还提供了将集合对象设置为不可变。
第九章 泛型
9.1泛型入门
集合忘记了对象的数据类型后,增加了编程的复杂性,也可能引发ClassCastException异常。
参数化类型被称为泛型。
Java允许在构造器后不需要再带完整的泛型信息,但还是要给出<>
9.2深入泛型
声明集合变量、创建集合对象时传入类型实参。
类型实参可以是创建类时也可以声明。
9.3类型通配符
Foo是Bar的一个子类型,而G是具有泛型声明的类和接口,G<Foo>并不是G<Bar>的子类型。但是Foo[]依然是Bar[]的子类型。
List<?>它的元素可以匹配任何类型,但并不能把元素加入其中。
List<? extends Shape>表示被限制的泛型通配符 所有Shape泛型的父类。所以不能把Shape对象或其子类的对象加入这个泛型集合中。
不仅允许在使用通配符时设置上限而且可以在定义类型形参时设置上限,也可以为类的类型形参设置多个上限。
第十章 异常
10.1概述
try:可能引发异常的代码;
catch:用于处理这种类型的代码块;
finally:用于回收物力资源。
throws:用于声明该方法可能抛出的异常;
throw:抛出一个具体的一样。
第十一章 AWT编程
第十二章 Swing编程
轻量级,可跨平台,取代AWT编程。
第十三章 JDBC基础
13.1基础
JDBC:可以执行SQL语句的Java API。
可以建立数据库的链接、执行SQL语句、获得SQL语句的执行结果。
第十四章 注释
14.1 概述
标记可以在编译、类加载、运行时被读取,可以在不改变原有逻辑的情况下,在原文件中嵌入一些补充的信息。
Override:强制一个子类必须覆盖父类的方法。
第十五章 I/O
15.1File
与平台无关的文件和目录,能新建、删除、重命名文件和目录。
系统总是依据用户的工作路径来解释相关路径。
15.2I/O流
输入、输出是从程序运行所在内存来划分的。
字节流InputStream和OutputStream,字符流Reader和Writer。
向特定IO设备读写的流,成为节点流;处理流用于对一个特定的流进行连接和包装,封装后的流来实现读和写。
15.3字节流和字符流
字节流处理的是字节,字符流操作的是字符。
构造器是一个物理节点,eg.文件名等。
15.4处理流
流的构造器是已经存在的流,效率更高。
关闭资源时,关闭最上层的处理流即可。
如果输入、输出的内容是文本内容,则应该考虑使用字符流;如果二进制则使用字节流。
管道流用于进程之间的通信。
缓冲流增加缓冲功能,可以提高效率。
对象流用于实现对象的序列化。
转换流用于将字节流转换为字符流:
InputStreamReader reader = new InputStreamReader();
BufferedReader br =new BufferReader(reader);
String line = null;
while((line = br.readLine())!=null)
{
system.out.println("line");
}
bufferedReader作为缓冲流,它可以一次读取一行文本,常常把读取文本内容的输入流包装成这个。
推回输入流可以讲内容推回到缓冲区里,从而允许重复读取刚刚读取的内容。
第十七章 网络
17.1基础
IP地址用于唯一地标示网络中的一个通信实体。
一个通信实体可以有多个通信程序同时提供网络服务则使用端口号。