《疯狂Java讲义》学习经验总结.docx
《《疯狂Java讲义》学习经验总结.docx》由会员分享,可在线阅读,更多相关《《疯狂Java讲义》学习经验总结.docx(86页珍藏版)》请在冰豆网上搜索。
《疯狂Java讲义》学习经验总结
《疯狂Java讲义》学习经验总结
第1章开发环境
1)Java程序运行机制:
Java是一种特殊的高级语言,*.java源文件先用javac编译,编译时并不生成特定平台的机器码,而是生成一种与平台无关的字节码(即*.class文件),然后由Java解释器来解释执行。
2)JVM(Java虚拟机,JavaVirtualMachine):
可解释并运行Java字节码文件的虚拟计算机,具有指令集并使用不同的存储区域,负责执行指令,还要管理数据、内存、寄存器、栈及垃圾回收堆。
不同平台的JVM都是不同的,不同平台的JVM向编译器提供相同的编程接口,只要为不同的平台实现了相应的虚拟机,编译后的Java字节码就可以在该平台运行。
3)JRE(Java运行时环境,RuntimeEnvironment):
包含JVM虚拟机及其他运行Java程序的环境支持。
4)Java开发环境搭建:
A.下载和安装JDK:
包含了编译和运行Java程序所需的各种工具和资源,包括Java编译器、JRE及常用的Java类库等。
安装时,选择不安装公共JRE;JRE会随DevelopmentTools安装。
JDK的安装路径不要包含空格,建议直接安装在根目录下。
标准版JavaSESDK下载链接:
B.设置PATH环境变量:
用于让不同的系统能够找到Java的可执行文件javac和java,位于bin目录下:
●Windows平台设置(不区分大小写):
控制面板=>系统=>环境变量=>新建用户变量(仅影响当前用户)=>PATH=D:
\jdk\bin;或修改系统变量(对所有用户有效)的Path环境变量。
●Linux平台设置(区分大小写):
修改home路径下的.bash_profile文件,修改PATH变量:
PATH=.:
$PATH:
$HOME/jdk/bin。
注意Linux多路径以冒号:
分隔,命令source使其生效。
C.注意:
只有使用早期版本的JDK时,才需要设置CLASSPATH环境变量,新版不再需要设置。
5)编写和运行Java程序:
Java程序的最小单位是类class,程序必须以类的形式存在
publicclassHelloWorld{
publicstaticvoidmain(String[]args){//程序的入口,必须照此格式书写,有且仅有一个
System.out.println(“HelloWorld!
”);
}
}
●编译:
javac–d.HelloWorld.java=>生成HelloWorld.class字节码文件,如在同目录下生成可省略d选项。
●运行Java程序:
java类名,如:
javaHelloWorld,不是class字节码文件,同时注意类名大小写
6)Java源文件的规定:
●注意Java严格区分大小写,需保存成java后缀的文件;Java中的所有关键字都是小写的。
●源文件名必须和文件里的public类相同,因此一个源文件里最多只能定义一个public类。
●推荐一个源文件只包含一个类,不同的类使用不同的源文件定义。
●Java是强类型语言,即所有变量必须先声明后使用,且指定类型的变量只能接受类型与之匹配的值。
7)包package:
将一组功能相关的类放在同一个包里,从而组成逻辑上的类库单元。
●需要在源文件的第一个非注释行声明包:
packagepackageName;
●包名应该采用公司域名倒写,且源文件需要放置在相应的目录结构中。
●父包和子包在用法上不存在任何关系,如需调用子包的类,必须使用子包的全名,不能省略父包部分。
●import关键字:
可以向某个Java文件中导入指定包层次下的某个类(指定类名)或全部类(用*代替)。
使用import可以省略写包名,使用importstatic则可以连类名都省略,直接调用方法和使用成员变量。
●如果导入的包中类名有冲突,则调用时必须指定包名和类名。
如:
java.sql.Dated=newjava.sql.Date();
●静态导入:
用于导入指定类的某个静态成员、方法或全部。
如:
importstaticpackage.sub.class.*;
第2章语法
1)文档注释:
以/**开始,*/结束,中间部分即文档注释。
通过javadoc工具将源码里的文档注释提取成一份系统的API文档。
javadoc工具默认只处理public或protected修饰的类、接口、方法、成员变量、构造器和内部类之前的文档注释。
/**
*
Description:
*@author/@version常用标记:
@author/@version/@param/@return
*/
javadoc–ddocdir–windowtitle浏览器标题–doctitle页面标题–header页眉–author–version*.java
2)分隔符:
每条语句必须以分号结束和分隔。
3)标识符:
必须以字母、下划线或$开头,后跟任意数目的字母、数字、下划线或$。
此处的字母可以包含中文字符。
需要注意标识符不能以数字开头,不能是java关键字和保留字,不能含其他字符,且大小写敏感。
4)关键字:
所有关键字都是小写的。
5)变量:
分为基本类型(包括boolean和数值类型),和引用类型(包括接口、类和数组,即对一个对象的引用)。
空类型(null)只能被转换为引用类型,不能转换为基本类型,即声明一个对象为null。
6)基本数据类型:
A.整型:
二进制以0b或0B开头,八进制以0开头,十六进制以0x或0X开头,a~f不区分大小写。
●byte:
一个字节8位,表数范围:
-27~127
●short:
两个字节16位,表数范围:
-32768~32767
●int:
4个字节32位,是最常用的和默认的整数类型。
●long:
8个字节64位,由于默认数字是int型,因此需要在数字后面加上l或者L作为后缀。
B.字符型:
用于表示单个的字符,必须用单引号‘括起来,使用16位的Unicode字符集作为编码方式。
●在保存时实际是2个字节16位的无符号整型,表数范围是0~65535,因此字符型可以参与运算
●直接通过字符赋值:
’A’、’9’
●通过转义字符表示特殊字符:
’\n’、’\t’、’\b’、’\r’、’\’’、’\”’、’\\’
●使用Unicode表示字符型值:
’\uXXXX’、’字’
●字符串是使用String类表示,必须用双引号“”括起来,变量是引用型变量,且特殊字符需要转义。
C.浮点型:
●float:
单精度浮点数,占4字节32位,第一位是符号位,接下来8位表示指数,再接下来23位表示尾数;不是默认浮点数类型,数值后面需要加f或F后缀。
●double:
默认浮点数类型,双精度浮点数,占8字节64位,第一位是符号位,接下来11位表示指数,再接下来52位表示尾数。
●三个特殊的浮点数:
Ø无穷大:
用于表示溢出,使用正的浮点数除以0得到正无穷大,用Double.POSITIVE_INFINITY表示;负的浮点数除以0得到负无穷大,用Float.NEGATIVE_INFINITY表示。
所有的正无穷大都是相等的,所有的负无穷大都是相等的。
整数除以0抛出异常:
ArithmeticException:
/byzero
Ø非数:
用于表示出错,0.0除以0.0或对一个负数开方将得到一个非数,用Float.NaN表示。
NaN不与任何数值相等,甚至和NaN都不相等。
●表示形式:
Ø十进制数形式:
必须包含一个小数点,否则会当做int型处理,如:
5.1、5.0、.5
Ø科学计数法:
5.12E2=5.12*102
D.数值中使用下划线分隔:
intbValue=0B1000_0000_0000_0001;doublepie=3.14_159_2653;
E.布尔型:
只能是true或false,不能用0或非0表示,其他基本数据类型也不能转换成boolean类型。
7)类型转换:
A.自动类型转换:
将表数范围较小的数值直接赋值给另一个表数范围较大的变量时,系统可以自动转换:
byte=>short(char)=>int=>long=>float=>double。
注意:
byte不能自动转换成char类型。
B.基本类型的字符串转换:
当基本类型和字符串进行连接运算时,基本类型将自动转换为字符串类型。
例如boolean类型的值和字符串进行连接运算,则会自动转为字符串。
例如:
Stringstr=true+“”;‘a’+7+“hello”输出104hello,“hello”+’a’+4输出helloa4
C.强制类型转换:
将浮点数强制转换为整数时,将直接截断小数部分。
如:
floatf=(float)5.6;
D.字符串转换为基本类型:
parseInt(str),对应类:
Boolean/Byte/Short/Integer/Long/Character/Float/Double。
E.表达式类型的自动提升:
当表达式包含多个基本类型时,整个表达式的数据类型将自动提升到其最高操作数的类型;所有的byte、short和char将提升到int类型。
例如一个short类型加一个数字将自动转换为int型,两个int型相除得到去除小数部分的int型,只要有一个是浮点数则转换成浮点型计算。
8)运算符:
A.算术运算符:
+、-、*、/、%求余(结果可能不是整数)、++、--
B.赋值运算符:
=。
注意:
赋值表达式是有值的,其值就是右边被赋的值。
如:
a=b=c=5;
C.位运算符:
&按位与、|按位或、~单目按位非、^按位异或、<<左移、>>右移、>>>无符号右移。
移位操作时,会将自动类型转换为int类型后再移位,左移相当于乘2,右移相当于除以2,且得到新的结果。
D.扩展赋值运算符:
+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>=、>>>=;好处在于无需数据自动提升。
E.比较运算符:
>、>=、<、<=、==、!
=,比较引用是否相当时,需要指向同一个对象才返回true。
F.逻辑运算符(比较布尔型变量):
&&(短路与,第一个为假即假)、&(不短路与)、||(短路或,第一个为真即真)、|(不短路或)、!
(非)、^(异或)。
G.三目运算符:
Stringstr=5>3?
“条件为真时的值”:
“条件为假时的值”;
9)循环结构:
使用break跳出多重循环:
Outer:
//定义标签:
紧跟冒号的标识符,且此标识符必须定义在循环语句之前
for(;;){
for(;;){
breakOuter;//直接跳出外层循环;continue语句语法与此类似
}
}
第3章数组
1)数组类型:
只能存储同样数据类型的数据,一旦初始化完成,数组空间将固定,长度不可改变。
A.定义:
type[]arrayName;//引用类型,定义时仅定义了一个引用变量(即指针),定义时不能指定长度。
B.二维数组:
type[][]arrayName;其实质依然是一维数组,数组中存放了指向另外数组的引用。
C.初始化:
为数组元素分配空间,并为每个元素赋初始值。
注意不能既指定长度又初始化初始值。
1.静态初始化:
int[]arr={5,6,7};arr=newint[]{5,6,7};
2.动态初始化:
int[]arr=newint[3];
3.初始化二维数组:
int[][]array=newint[3][4];String[][]strArray={newString[3],newString[]{“hi”}};
D.长度:
数组的length属性
E.for循环遍历数组:
for(Stringbook:
bookArray){;}//book会自动迭代每个数组元素,不要给其赋值
F.数组的存储:
实际存储在堆内存中,不会随着方法结束而销毁。
G.数组的引用变量:
定义在方法创建的临时栈内存中,方法结束时这个内存栈也会被销毁,但其指向的数组对象不会被销毁。
只有当一个对象没有任何引用变量引用它时,系统的垃圾回收器才会在合适的时候回收它,因此在不使用数组时需要将引用变量置为null。
2)增强的Arrays类:
以下静态方法是类的方法,可以直接调用,如:
Arrays.sort(a);
A.intbinarySearch(type[]a,typekey):
二分法查询key元素在数组a中的索引,不存在则返回负数。
要求该数组元素已经按照升序排列。
B.intbinarySearch(type[]a,intfromIndex,inttoIndex,typekey):
查询指定范围内的元素索引
C.type[]copyOf(type[]original,intlength):
复制新数组,length不足切断,超过补零。
D.type[]copyOfRange(type[]original,intfrom,intto):
复制参数指定的元素到新数组。
E.booleanequals(type[]a,type[]b):
当数组长度及元素一一相等时,返回真。
F.voidfill(type[]a,typeval):
将数组所有元素赋值为val。
G.voidfill(type[]a,intfromIndex,inttoIndex,typeval):
指定范围内的元素赋值。
H.voidsort(type[]a)/voidsort(type[]a,intfromIndex,inttoIndex):
排序。
I.StringtoString(type[]a):
数组转换为字符串,元素间用英文逗号和空格隔开。
J.System类的方法:
staticvoidarraycopy(Objectsrc,intsrcPos,Objectdest,intdestPos,intlength);
K.Java8增强的并行数组处理函数:
P101
第4章面向对象(上)
1)类的定义(类的三大特征:
封装、继承和多态):
[public/final/abstract]class类名{//类名规范:
每个单词首字母大写,单词间没有分隔符和连接符
零到多个构造器定义:
[public/protected/private]类名(形参列表);其中构造器名必须和类名相同;不能定义返回值类型;系统会提供默认的构造器,如果自己提供了构造器,则系统不再提供。
通常定义public类型的构造器,protected一般用于被子类调用,如果设置为private,则阻止创建该类的实例。
零到多个成员变量定义:
[public/protected/private][static][final]类型成员变量名[=默认值]成员变量名应该首字母小写,后面每个单词首字母大写,单词间没有分隔符和连接符
零到多个方法定义:
[public/protected/private][static][abstract/final]返回值类型方法名(形参列表);如果没有返回值,需要声明为void;命名时以英文动词开头,首字母小写。
}
2)static关键字:
可以修饰方法、成员变量,表明其属于类,而非某个实例。
调用方法:
类名.类变量/类方法。
静态成员不能直接访问非静态成员,且不能在static修饰的方法中使用this引用(因为是类的方法,而this指向一个实例)。
如果一定要在静态方法中调用普通方法,就必须声明一个实例并调用。
Java允许实例调用类方法,但是不推荐这样的写法。
3)访问控制级别表:
private
default
protected
public
同一个类中
√
√
√
√
同一个包中
√
√
√
子类中
√
√
全局范围内
√
Øpublic:
如果源文件没有public类,则此文件名可以是一切合法的文件名;只要源文件有一个public类,则此文件名必须和这个public修饰的类名相同。
Øprotected:
通常都是希望子类来重写这个方法。
Øprivate:
成员变量应该尽量声明为private来实现封装,并提供setter和getter方法用于访问。
4)创建实例:
Personp=newPerson();其中p称为引用变量(存放于方法栈中),其指向堆中创建的对象实例。
5)对象的this关键字和引用:
this总是指向调用该方法的对象。
当方法中的局部变量和成员变量重名时,必须使用this关键字。
位于构造器中的this指向正在初始化的对象。
6)方法的参数传递机制:
只有一种,即值传递,即将参数的副本传入方法内,原参数不会受到影响。
7)形参个数可变的方法:
可变参数只能位于参数列表的最后,因此只能有一个可变参数
publicvoidtest(inta,String…books){//本质等同于数组参数定义:
test(inta,String[]books);
for(Stringtmp:
books){}//调用方法:
test(5,“字符串一”,“字符串二”,“字符串三”);也可传入一个数组
}
8)方法的重载:
如果同一个类中定义了多个方法名相同但形参列表不同的方法,则称为方法的重载,与返回值定义无关。
9)构造器的重载和相互调用:
通过定义不同的参数列表可实现构造器的重载。
如果需要在构造器中调用其他的构造器,则需使用this作为函数名。
如:
this(param);注意此调用方法必须写在构造方法的第一条语句。
10)方法中的局部变量:
必须先给方法中的局部变量和代码块局部变量指定初始值,否则不可以访问它们。
同名的局部变量会覆盖成员变量,可以使用this关键字访问成员变量。
11)封装:
将成员变量隐藏,外部必须通过方法来访问,可以隐藏实现细节,另外执行数据检查,防止不合理访问。
如果每个变量都用private修饰,且提供了public修饰的setter和getter方法,则称此类是一个符合JavaBean规范的类。
12)继承:
每个类只能有一个直接父类,但是可以有多个间接父类。
java.lang.Object是所有类的父类。
A.定义:
[]classSubClassextendsSuperClass{}
B.重写父类的方法:
子类包含与父类同名的方法且形参列表相同,返回值需小于等于父类,访问权限需大于等于父类,且必须同为类方法或实例方法。
C.如果需要调用父类中被覆盖的方法,可以使用super关键字(实例方法)或父类名(类方法)调用。
D.程序会为子类自己定义的所有变量和从父类继承的所有变量分配空间。
如果子类覆盖了父类同名的成员变量,也使用super访问。
如果将子类向上强制转换为父类,则访问的就是父类的同名变量。
E.重载和重写的区别:
重载是指同一个类的多个同名方法,重写是指子类和父类的同名方法。
F.变量查找顺序:
局部变量》当前类的成员变量》直接父类的成员变量》所有父类的成员变量。
G.调用父类的构造器:
super(param);使用时必须出现在子类构造器执行体的第一行,和this调用不能同时出现。
如果没有显式的super调用,则系统会在执行子类构造器之前,隐式调用父类无参数的构造器。
因此,创建任何对象时,最先执行的总是java.lang.Object类的构造器。
13)多态(Polymorphism):
当把一个子类对象直接赋值给父类的引用变量时,会导致编译时类型和实际运行时类型不一致,若此时子类有覆盖父类的方法,这时引用的方法总是表现出子类方法的行为特征,而非父类的方法。
与方法的多态性不同,对象的实例变量并不具备多态性,如果有覆盖父类的成员变量,此时调用的总是父类的实例变量,即编译时确定的变量类型。
原因在于子类的同名方法是真覆盖,所以调用的时候只能调用运行时已经覆盖的子类方法。
而同名成员变量则是假覆盖真隐藏,调用时还是编译时的父类变量。
14)引用变量的强制类型转换:
(type)variable
A.基本类型的转换只能在数组类型之间进行,包括整型、字符型和浮点型,不包括布尔类型。
B.引用类型之间的转换只能在具备继承关系的两个类型之间进行,并且将子类转换为父类总是可以成功。
C.当把父类转换为子类时,需要先通过instanceof运算符来判断是否可以成功转换。
例程:
If(objectinstanceofClass){Classvariable=(Class)object;}
15)组合:
继承会破坏父类的封装,如直接访问父类成员变量及覆盖父类方法。
如果在父类构造器中调用了子类重写的方法,则初始化时首先调用父类构造器,但是实际又调用了子类的覆盖同名方法,这个时候就会由于子类的构造器还未调用,如果此时调用子类的成员变量,就会导致空指针异常。
如果只是希望利用类的方法,可以采用组合的方法,即将此类作为新类的私有成员变量,这样就可以使用类的方法和变量。
如:
ClassSubClass{//继承表达的是一种是(is-a)的关系,组合表达的是一种有(has-a)的关系。
privateBaseClassa;//将需要利用的类作为私有成员变量
publicSubClass(BaseClassa){this.a=a;}//通过构造函数赋值
publicvoidfunction(){a.func();}
}//调用时需要首先创建BaseClass并将此实例初始化SubClass
16)初始化块:
初始化块是一段固定执行的代码,不接受任何参数。
创建对象时,系统先调用初始化块,且在执行构造器之前执行。
实际上编译后初始化块的代码会编译到每个构造器的代码的最前面。
例程:
ClassClassName{
static{}//静态初始化块,用于初始化类变量,创建时会从顶层开始调用所有的静态初始化块
{}//普通初始化块,用于初始化实例变量,不能初始化类变量
}
第5章面向对象(下)
1)Java8增强的包装类:
为8种基本数据类型分别定义了相应的引用类型,称为基本数据类型的包装类。
byte=>Byte
short=>Short
int=>Integer
long=>Long
char=>Character
float=>Float
double=>Double
boolean=>Boolean
Ø自动装箱(AutoBoxing)和自动拆箱(AutoUnboxing):
即包装类可以自动和对应的基本数据类型相互转换。
如:
IntegerintObj=5;inta=intObj;ObjectboolObj=true;booleanb=(Boolean)boolObj;
Ø字符串转换为基本类型变量:
利用包装类的parseXxx(Strings)静态方法或Xxx(Strings)构造器。