课后习题
第01章 语言概述
谈谈你过去学习编程语言的方法、经验和教训。
学习过C++和Python, 基本方法是学习简单语法,尝试做简单的题目,这样能够很快的熟悉一门语言。而后在尝试写一些简答的项目,比如Python的爬虫数据分析等。
高级语言的编译型和解释型语言的编译执行过程有什么区别?
高级语言编译一次性全部编译成机器码,解释性是一句一句转成机器码
Java语言都有哪些特点?与C, C++, Python有何不同?
Java是完全的面向对象编程
Java实现跨平台的原理是什么?
通过java虚拟机在系统平台上运行的,而不同平台有不同的虚拟机。具体流程:
源文件(.java)—>字节码文件(.class)(二进制文件)—–> 解释—->Unix,Win,Linux等机器
JDK、JRE、JVM分别是什么的简称,它们之间有何联系和区别?
- JDK(Java Development Kit):是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的Java应用程序。JDK是整个Java开发的核心。
- JRE(Java Runtime Environment):是指Java的运行环境,是可以在其上运行、测试和传输应用程序的Java平台。
- JVM(Java Virtual Machine):是java虚拟机,是一种用于计算设备的规范,它是一个虚构出来的计算机,引入JVM后,Java语言在不同平台上运行时不需要重新编译。JVM是Java跨平台的核心。
- 联系
- JDK包含了java的运行环境(JRE)和Java工具。
- JRE包含了一个Java虚拟机(JVM)以及一些标准的类别函数库。
- 区别:
- JDK和JRE区别:在
bin文件夹下会发现,JDK有javac.exe而JRE里面没有,javac指令是用来将java文件编译成class文件的,这是开发者需要的,而用户(只需要运行的人)是不需要的。JDK还有jar.exe, javadoc.exe等等用于开发的可执行指令文件。这也证实了一个是开发环境(JDK),一个是运行环境(JRE); - JRE和JVM区别:JVM并不代表就可以执行
class了,JVM执行.class还需要JRE下的lib类库的支持,尤其是rt.jar。
- JDK和JRE区别:在
第02章 语言基础
Java包含哪两大类数据类型?其中基本类型的每种类型的取值范围和默认值分别是什么?请编程验证。- 基本数据类型
- 整数类型
- 浮点类型
- 字符类型
- 布尔类型
- 引用数据类型
- 类类型
- 接口类型
- 数组类型
- 验证:

- 基本数据类型
Java在什么情况会发生整型溢出?请举例说明,并给出解决方案。- 超出数据类型的范围
- 解决方法:
- 换成更大范围的类型
- 手写高精度算法
Java基本类型的包装类分别是哪些?其高频区间数据缓存范围分别是什么?请选择一种包装类型编程验证其数据缓存特性。基本数据类型 包装类 字节数 位数 默认值 数据范围 高频区间数据缓存范围 byte Byte 1 8 0 $[-128,127]$ short Short 2 16 0 $[-32768,32767]$ $[-128,127]$ int Integer 4 32 0 $[-2^{31}, 2^{31}-1]$ $[-128,127]$ long Long 8 64 0L $[-2^{63},2^{63}-1]$ $[-128,127]$ float Float 4 32 0.0f 无缓存 double Double 8 64 0,0d 无huancub boolean Boolean 1 8 false char Character 2 16 ‘\u0000’ $[0,127]$ 1
2
3
4
5
6
7
8
9
10Integer i3 = 128;
Integer i4 = 128;
i3 == i4 // false
Integer i3 = 127;
Integer i4 = 127;
i3 == i4 //true
//比较指向的对象是否一致
//逻辑比较请用equal什么是自动装箱,什么是自动拆箱,请举例说明。
1
2
3
4
5
6
7Integer varInteger=100;//自动装箱
//等价于
integer varInteger=Integer.valueOf(100);
int varInt=varInteger;//自动拆箱
//等价于
int varInt=varInteger.intValue();int与Integer有什么区别,它们之间的相互转化是怎样的?请通过JDK文档自主学习Integer类,对主要方法进行测试。Integer是int的包装类,默认值分别为null和0Integer需要实例化才可以使用,int不需要。(不包括自动拆箱装箱)int->Integer1
2
3int a=66; Integer A=new Integer(a);
//等价于
Integer A=Integer.valueOf(a);Integer->int1
2Integer A=new Integer(66);
int a=A.intValue();
逻辑运算符
&和&&的区别是什么?逻辑运算符&与位运算符&的区别是什么?&&是短路判断语句,只要前半个为错误,就不会判断后面的语句了&会将所有语句都跑一边,看是否存在错误。- 两者比较,
&&更高效。 - 作为逻辑运算符,两边为表达式
- 作为为运算符,两边为数字
Java语言中可以采用什么语句跳出多重循环?请举例说明break跳出当层循环continue跳出当次循环跳回到标签位置:
1
2
3
4
5
6
7
8post:
for(int i=1;i<=10;i++){
for(int j=1;j<=10;j++){
if(i+j>=5) break post;
//System.out.println(i+j);
}
}
}
请总结
Java语言与C/C++在基本数据类型、运算符、表达式、控制语句方面的不同。布尔常量的
true false和1 0不等价,不可直接运算。字符串作为对象,有自己的方法和属性。
C/C++则是\\0结束的字符数组变量未赋值有默认值,而
C/C++是不确定的。不支持自动强制类型转换,需手动转换。
有支持多线程的库,
C/C++需要自己写。前者是先编译,后解释执行,后者是纯编译型,速度后者更快,但是移植型前者更好。
借鉴博客连接:
第06章 继承与多态
实验:利用IDE的debug功能给P5示例的
new语句设置断点,使用单步调试(step into/step over)跟踪对象实例化(初始化)的执行顺序,并总结该过程。1
2
3
4
5
6
7
8
9
10
11
12class AddClass {
public int x=0,y=0,z=0;
AddClass (int x) {this.x = x;}
AddClass (int x,int y) {this(x);this.y = y;}
AddClass (int x,int y,int z) { this(x,y); this.z = z; }
public int add() {return x+y+z;}
}
public class RunAddClass {
public static void main(String[] args) {
AddClass p1=new AddClass(2,3,5);
}
}- 访问三变量构造函数
- 通过
this(x,y)调用两变量构造函数 - 同理,调用一变量构造函数
- 给变量
x赋值 - 返回 两变量构造函数 给
y赋值 - 返回 三变量构造函数 给
z赋值
实验:利用IDE的
debug功能给P12,P13示例的new语句设置断点,使用单步调试(step into/step over)跟踪子类对象实例化(初始化)的执行顺序,并总结该过程。1
2
3
4
5
6
7
8
9
10
11//显式
public class SonAddClass extends AddClass{
int a=0,b=0,c=0;
SonAddClass (int x) {super(x);a=x+7;}
SonAddClass (int x,int y){super(x,y); a=x+5; b=y+5;}
SonAddClass (int x, int y,int z){ super(x,y,z); a=x+4; b=y+4;c=z+4;
}
public static void main(String[] args){
SonAddClass p1=new SonAddClass (2,3,5);
}
}- 访问三变量子构造函数。
- 通过
super访问父类三变量构造函数。 - 同上文顺序给父类三变量赋值
- 返回子类构造函数,给子类变量赋值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23//隐式
package test;
class Pare {
int i=3;
Pare(){ System.out.println("call super()"); }}
class Construct extends Pare{
int i = 10;
Construct(){System.out.println("execute Construct()"); }
Construct(int num){ this(); //如果注释掉该句呢?
System.out.println("execute Construct(int)"); }
public static void main(String[] args){
Construct ct = new Construct(9);
System.out.println(ct.i);}}
//注释前
call super()
execute Construct()
execute Construct(int)
10
//注释后
call super()
execute Construct(int)
10分析P7示例的程序执行过程,画出程序执行的内存布局。(蒙的)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28package test;
class A {
int x=4;
int y=1;
public void Printme() {
System.out.println("x="+x+" y="+y);
System.out.println("class name: "+getClass().getName());
}
}
public class AA extends A {
int x;
public void Printme() {
int z=super.x+6;
super.x = 5;
super.Printme();
System.out.println("I am an "+getClass().getName());
x=6;
System.out.println(" z="+z+" x="+x+" super.x="+super.x +" y="+y+"super.y="+y);
}
public static void main(String arg[]) {
int k;
A p1=new A();
AA p2=new AA();
p1.Printme();
p2.Printme();
}
}
总结
this与super的用法。this.调用本对象的属性或方法,this()调用本对象的构造方法super.调用父对象的属性和方法,super()调用父对象的构造方法- 两者都要放到第一句,所以不可同时使用。
论述组合与继承的区别以及两者的使用场景(即什么时候宜用组合?什么时候宜用继承?)
- 都是代码的复用
- 组合中,各类是独立的,继承中,子类缺乏独立性
- 从一般到特殊选择继承
- 作为工具类选择组合
Java中的运行时多态的含义是什么?通常在什么场景下应用,请举例说明。- 多态含义:同一个类有多个对象,接收到同一个消息时,会有不同的结果
- 运行时多态:使用父类引用,指向子类对象,再调用某一父类中的方法时,不同的子类会表现出不同的结果。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48public class Figure {
double dim1;
double dim2;
Figure(double d1, double d2) {
// 有参的构造方法
this.dim1 = d1;
this.dim2 = d2;
}
double area() {
// 用于计算对象的面积
System.out.println("父类中计算对象面积的方法,没有实际意义,需要在子类中重写。");
return 0;
}
}
public class Rectangle extends Figure {
Rectangle(double d1, double d2) {
super(d1, d2);
}
double area() {
System.out.println("长方形的面积:");
return super.dim1 * super.dim2;
}
}
public class Triangle extends Figure {
Triangle(double d1, double d2) {
super(d1, d2);
}
double area() {
System.out.println("三角形的面积:");
return super.dim1 * super.dim2 / 2;
}
}
public class Test {
public static void main(String[] args) {
Figure figure; // 声明Figure类的变量
figure = new Rectangle(9, 9);
System.out.println(figure.area());
System.out.println("===============================");
figure = new Triangle(6, 8);
System.out.println(figure.area());
System.out.println("===============================");
figure = new Figure(10, 10);
System.out.println(figure.area());
}
}
//figure 的对象都是其子类。向上转型,实现多态。使用接口改写例6.8中的程序。
论述抽象类与接口的异同以及两者的使用场景。

论述内部类的定义和作用以及匿名内部类的使用。
- 定义:在类的内部定义类
- 作用:可以访问外部类的成员,包括私有成员,使得该类具有其他类没有的特有功能。
第 07 章 异常
Throwable的子类包含哪两类?简述Error类与Exception类的区别。- 前者不可被捕获,后者可以被捕获
- 前者不需要被抛出,后者需要用
Expetion抛出异常 - 前者会导致程序不能运行或中断,后者可以通过捕获抛出
Exception又分为checked异常和unchecked异常,请分别举例说明。前者是在编译是需要检查的异常,需要用
try - catch捕获,后者是不需要在编译时处理。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// checked
class A{
public static void main(String[]args){
try(Scanner sc=new Scanner(System.in)){
int a=sc.nextShort();
}catch (Exception e){
e.printStackTrace();
}
}
}
//unchecked
class A{
public static void main(String[]args){
int []a;
System.out.println(a[0]);
}
}
请查阅资料,简述
StackOverflowError和OutOfMemoryError两类错误的发生情形和原因。- 前者:递归次数太多、线程数量太多
- 后者:内存不够发生了内存溢出
简述异常处理的两种方式,并举例说明区别。
throw异常上抛,如果直接抛到了main就会结束程序try - catch异常捕获处理,调用者不会知道哪里出错了,因为在下面已经被捕获并且处理了。
选取
RuntimeException类的五个子类,编写抛出并捕获上述子类异常的程序。(例如算术异常,空指针异常,类转换异常,数组越界异常等)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37public class Exception {
public static void main(String args[]){
try{
int a=1/0;
}catch (java.lang.Exception e){
System.out.println("算术异常:"+e);
}
try{
int []a = new int[10];
a[11]=-1;
}catch (java.lang.Exception e){
System.out.println("数组越界异常:"+e);
}
try{
Scanner sc = null;//new Scanner(System.in);
sc.nextInt();
}catch (java.lang.Exception e){
System.out.println("空指针异常:"+e);
}
try{
Stack<Integer> stack = new Stack<>();
stack.pop();
}catch (java.lang.Exception e){
System.out.println("空栈异常:"+e);
}
try{
Object a = new Integer(0);
a=(String)a;
}catch (java.lang.Exception e){
System.out.println("类转换异常:"+e);
}
}
}根据某业务场景自定义一个异常类,并在某场景下抛出该异常对象。
关于自定义异常类:
1
2
3
4
5
6
7
8
9
10
11
12public class SelfException extends java.lang.Exception {
public SelfException(){}
public SelfException(String s){
super(s);
}
public static void main(String args[]) throws SelfException {
int a = 1;
if(a == 1){
throw new SelfException("a=1");
}
}
}异常中的
throws声明与throw语句的区别是什么?请举例说明。 1.finally子句的作用是什么?
第 08 章 字符串
借助
JDK文档, 选取String与StringBuffer、StringBuilder的常用API,并编写实例测试API的功能。请简述
String,StringBuffer,StringBuilder三者之间的共同点与区别,应该分别在何种场景下使用?- 相同点
- 都是字符串类
- 内部基于字符数组实现,封装了对字符串的各种操作
- 不同点
String是不可变的,每次改变会重新创建对象。支持共享StringBuffer是线程安全的,可变的StringBuilder是多线程不安全的,可变的,相比StringBuffer更快。提供了和StringBuffer兼容的API,但不保证同步。
- 使用场景
- 多线程使用字符串缓冲区时,使用
StringBuffer是更为安全的 - 效率上讲
StringBuilder>StringBuffer>String
- 多线程使用字符串缓冲区时,使用
- 相同点
为什么不建议在for循环中使用“+”进行字符串拼接?
String是字符串常量,每次改变都会生成一个新的对象,会十分影响性能。
第 09 章 多线程
创建线程的基本方法有哪些?
- 通过继承
Thread类 - 通过实现
Runnable接口
- 通过继承
FutureTask类有什么作用?它实现了哪些接口?volatile关键字有什么作用?- 保证程序的可见性和有序性(不能保证原子性)
Java提供了哪些同步机制来实现互斥?synchronizedReentrantLock
编写
Java程序模拟烧水泡茶最优工序。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102package Acwing;
class WashKettle implements Runnable{
public void run() {
System.out.println("开始洗水壶");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("水壶洗完了");
}
}
class HeatWater implements Runnable{
public void run(){
System.out.println("开始烧水");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("水烧完了");
}
}
class WashCup implements Runnable{
public void run() {
System.out.println("开始洗茶杯");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("茶杯洗完了");
}
}
class GetTea implements Runnable{
public void run() {
System.out.println("开始拿茶叶");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("茶叶拿完了");
}
}
class Finish implements Runnable{
public void run() {
System.out.println("开始泡茶");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("茶泡完了");
}
}
public class Tea {
public static void main(String args[]) throws InterruptedException {
Thread t1 = new Thread(new WashKettle());
Thread t2 = new Thread(new HeatWater());
Thread t3 = new Thread(new WashCup());
Thread t4 = new Thread(new GetTea());
Thread t5 = new Thread(new Finish());
t1.start();
t1.join();
t2.start();
t3.start();
t3.join();
t4.start();
t4.join();
t2.join();
t5.start();
}
}
/*
开始洗水壶
水壶洗完了
开始烧水
开始洗茶杯
茶杯洗完了
开始拿茶叶
茶叶拿完了
水烧完了
开始泡茶
茶泡完了
*/阅读公众号“码农翻身”的文章—《我是一个线程》。
第 10 章 JavaIO
Java中流的分类有哪些?- 输入流、输出流
- 字节流、字符流
- 节点流、过滤流
字节流
InputStream和OutputStream的子类分别有哪些?请编程举例说明其使用场景。与其对应的字符流分别有哪些?1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
byte[] b = "hello".getBytes();
//ByteArrayInputStream
//字节数组和流之间的桥梁
ByteArrayInputStream bais = new ByteArrayInputStream(b);
int n = 0;
while((n = bais.read())!=-1){
System.out.print((char)n);
}
//FileInputStream
//文件和流之间的桥梁
try{
FileInputStream rf = new FileInputStream("C:\\\\Users\\\\JMhhh\\\\Desktop\\\\hello.txt");
int n2 = 512,c = 0;
byte[] b2 =new byte[n2];
while((c = rf.read(b2,0,n2))!=-1){
String s = new String(b2,0,c);
System.out.println(s);
}
rf.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
//PipedInputStream
//一个程序的输出连接到另一个的输入
PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream();
in.connect(out);
new Thread(new Input(in)).start();
new Thread(new Output(out)).start();
//ObjectInputStream
//对象的序列化传输——恢复
people p1 = new people("sda",10);
ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream("C:\\\\Users\\\\JMhhh\\\\Desktop\\\\hello.txt"));
oout.writeObject(p1);
ObjectInputStream oin = new ObjectInputStream(new FileInputStream("C:\\\\Users\\\\JMhhh\\\\Desktop\\\\hello.txt"));
people O = (people) oin.readObject();
System.out.println(O.name);
}
}
class people implements Serializable {
public String name;
public int old;
public people (String name,int old){
this.name = name;
this.old = old;
}
}字节流与字符流的转化是怎样的?
Java对此提供了哪些支持?- 提供了
InputStreamReader类和OutputStreamWriter类为字节流和字符流之间实现相互转换。 - 前者将字节流解码成字符,后者将字符转成字节写入流
- 提供了
Java中的过滤流(流的装配)有什么作用?请编程举例说明常用的过滤流。功能:
可从字节流中写入,读取Java基本数据类型,不依赖机器的具体数据类型,方便存储和恢复数据
1
2
3
4
5
6
7
8
9
10
11DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("C:\\Users\\JMhhh\\Desktop\\hello.txt")));
dos.writeInt(3);
dos.writeUTF("sda");
dos.writeDouble(3.14);
dos.close();
DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("C:\\Users\\JMhhh\\Desktop\\hello.txt")));
System.out.println(dis.readInt());
System.out.println(dis.readUTF());
System.out.println(dis.readDouble());
dis.close();用于缓存字符流,可以一行一行的读
1
2
3
4
5BufferedReader bin = new BufferedReader(new InputStreamReader(System.in));
for(int i=1;i<=3;i++){
String s = bin.readLine();
System.out.println(s);
}
什么是对象的序列化和反序列化?
Java对此提供了哪些支持?对象序列化用于什么情形?请编程相关示例。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15people p1 = new people("sda",10);
ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream("C:\\Users\\JMhhh\\Desktop\\hello.txt"));
oout.writeObject(p1);
ObjectInputStream oin = new ObjectInputStream(new FileInputStream("C:\\Users\\JMhhh\\Desktop\\hello.txt"));
people O = (people) oin.readObject();
System.out.println(O.name);
class people implements Serializable {
public String name;
public int old;
public people (String name,int old){
this.name = name;
this.old = old;
}
}Java的File类表示什么?有什么作用?- 访问文件和目录,文件属性等

Java对文件的读写分别提供了哪些支持?- 文件输入输出流的类
第 11 章 网络编程
- 基于
TCP Socket的C/S通信与基于UDP数据报的C/S通信有哪些区别?Java分别提供了哪些支持 - 编写一个基于
TCP Socket套接字的C/S聊天器程序。 - 编写一个基于
UDP数据报的C/S聊天器程序。
泪和对象
- 对象和对象的引用
1 | new dog();//创建对象,规划堆(heap)内存,没有引用则为孤儿,自动回收 |
- 参数传递
- 简单类型作为变量参数
1 | pubilc class ValuePass{ |
- 对象引用变量作为参数
1 | class InsClass{ |
- 数组对象
- 声明格式
1 | int [] arr; |
- 数组初始化对象
1 | int[] arr=new int[10];//在堆上为数组对象分配整型空间,默认为0; |
- 二维数组
1 | int arr[][]//数组声明 |
- Static 和 final 修饰符
static数据成员初始化:静态数据成员仅在类加载时进行初始化,且只执行一次初始化、首次访问某类的静态字段或静态方法是,会加载该类,并执行静态初始化语句
静态方法:
1 | class IntClass{ |
final修饰属性,则属性为常量
1 | final int NUM=20; |
final修饰方法,则该方法在子类当中不能被覆盖
1 | class Parent{ |
final修饰类,则该类不能被继承
1 | class Parent{ |
- 包(
package)
1 | //被访问 |
第五章 封装、继承与多态
1 | public void setName(String_name){ |
一、封装
- 访问权限控制符
publc(公共访问权限)protected(包访问权继承访问权限)- 无访问控制符修饰(默认为包访问权限)
private(类内部访问权限)
二、继承
- 通过
extends关键字实现 - 子类继承了父类的所有属性和方法,但只有
public、protected的属性和方法在子类是可见的。
三、多态
多态的概念:多态是指一个程序中同名的不同方法共存情况
Java中提供两种多态机制 重载
overloading与 覆写overriding a.重载:方法名称相同,参数类型或个数不同
1
2
3
4
5
6
7
8
9
10
11
12class stuMange{
public int getScore(int i){
return i;
}
public int getScore(Integer i){
return i;
}
public int getScore(int ... i){//可能有多个参数
return 3;
}
}
p.getScore(5) //调用优先级:1>2>3 b.覆写:子类堆父类的同名方法重新进行定义。
(i)子类的访问修饰符权限应大于等于父类。
(ii)应该能够向上转型为父类的返回类型。
1
2
3
4
5
6
7
8
9
10
11class Parent{
Number getScore(int a){
return Integer(7);
}
}
class Son extends Parent{
//帮忙检查是否覆写
Number getScore(int b){
return new INteger(8);
}
}
第六章 继承与多态
一、 this 与 super
this- 主要应用场合:
- 表示当前对象引用,常用与形参或局部变量与类成员变量同名的情形,使用
this.成员名表示当前对象的成员。 - 调用当前类的构造方法
- 表示当前对象引用,常用与形参或局部变量与类成员变量同名的情形,使用
- 主要应用场合:
super访问当前类的直接父亲,主要应用场合:子类的数据成员或成员方法与父类的数据成员或成员方法名字相同时,当要调用父亲的痛,同名方法或同名数据成员时则可用
super.数据成员、成员方法。super(参数列表),表示现实调用父类构造方法,对子类对象中从父类继承过来的数据成员进行初始化。显式使用
super调用父类的构造方法1
2
3
4
5
6
7
8
9
10
11
12
13class AC{
private int x=0,y=0,z=0;
AC (int x){
this.x=x;
}
}
public class SonAC extends AC{
int a=0,b=0,c=0;
SonAC (int x){
super(x);//调用父类构造方法
a=x+7;
}
}隐式使用
super调用父类的构造方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27class Pare{
int i=3;
Pare(){
System.out.println("call super()");
}
}
class Construct extends Pare{
int i=10;
Construct(){
System.out.println("execute Construct()");
}
Construct(int num){
this();
System.out.println("excute Construct(int));
}
public static void main(String[] args){
Construct ct=new Construct(9);
System.out.println(ct.i);
}
}
//输出结果
/*
call super()
ececute Construct()
execute COnstruct()
10
*/
二、抽象类
抽象类:用
abstract修饰的类称为抽象类,用abstract修饰的成员方法称为抽象方法。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public abstract class A{
private int m;
public abstract void a();//抽象方法
public abstract void b();//抽象方法
public void c(){//非抽象方法可以调用抽象方法
a();
}
}
abstract class B extends A{
public void b(){}//仅实现抽象方法b()
}
class C extends B{
public void a(){}//实现抽象方法a()
}抽象类的应用:抽象类和具体类的关系就是一般类和特殊类之间的关系,在继承体系中对外提供抽象的子类公共的行为接口。
三、接口 interface
接口声明
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public interface InterfaceA {
public static final int ON = 1;
public abstract void a();
}
public interface InterfaceB {
public abstract void b();
}
public interface InterfaceC extends InterfaceA, InterfaceB {
public abstract void c();
}
public class InterfaceImp implements InterfaceC{
public void a() { //必须public,权限不能缩小
System.out.println("call a()");
}
public void b() {
System.out.println("call b()");
}
public void c() {
System.out.println("call c()");
}}注意事项
- 接口定义用关键字
interface,而不是用class,interface前的修饰符要么为public,要么为缺省。 - 在类中,用
implements关键字来实现接口。一个类可以实现多个接口,在implements后用逗号隔开多个接口的名字。一个接口也可被多个类来实现。 - 接口具有继承性,可通过
extends关键字声明接口的父接口列表。 - 接口定义的数据成员全是
public final static(静态常量),即使没有修饰符。存储在该接口的静态存储区域内,使用接口名.字段或实现类.字段均可访问。 - 接口中没有构造方法;所有的抽象方法都是
public abstract方法(与抽象类有所不同)。即使没有修饰符,其效果完全等效。注:方法前不能修饰为final。 - 如果实现某接口的类不是
abstract修饰的抽象类,则在类的定义部分必须实现接口的所有抽象方法,而且方法头部分应该与接口中的定义完全一致。 - 如果实现接口的类是
abstract类,则它可以不实现该接口的所有方法。但对于抽象类的任何一个非抽象的子类而言,接口中的所有抽象方法都必须实现。 - 类在实现接口的抽象方法时,必须显式使用public修饰符,否则将被警告为缩小了接口中定义的方法的访问控制范围。
- 接口定义用关键字
实现过程
定义接口
1
2
3
4
5
6
7
8
9
10public interface Washer {
public static final int ON = 1 ;
public static final int OFF = 0 ;
abstract void startUp(); //启动
abstract void letWaterIn(); //进水
abstract void washClothes(); //洗衣
abstract void letWaterOut(); //排水
abstract void stop(); //停止
}实现接口
1
2
3
4
5
6
7
8class RoseBrand implements Washer{
public void startUp(){ System.out.println("startUp");}
public void letWaterIn(){System.out.println("letWaterIn");}
public void washClothes(){System.out.println("washClothes");}
public void letWaterOut(){System.out.println("letWaterOut");}
public void stop(){System.out.println("stop");}
public void dehydrate(){System.out.println("dehydrate ");}//脱水
}使用接口
1
2
3
4
5
6
7
8
9
10
11
12
13public class Consumer {
public static void main(String args[]){
//接口声明引用实现接口的RoseBrand类的对象。
Washer w = new RoseBrand();
w.startUp();
w.letWaterIn();
w.washClothes();
w.letWaterOut();
w.stop();
//w.dehydrate ();当通过接口调用玫瑰洗衣机类独有的,
//接口未定义的功能方法,编译会报错。
}
}
抽象类与接口
相同点:二者都可具有抽象方法,都不能实例化,但都可以有自己的声明,并能引用子类或实现类对象。
不同点:
| 特性 | 抽象类 | 接口 |
|---|---|---|
| 组合 | 子类只能继承单一抽象类 | 实现类可以继承多个接口 |
| 属性 | 可以包含一般属性,非抽象方法可以引用这些属性 | 只有静态属性,不支持对象状态 |
| 方法 | 在子类中实现抽象方法 | 在实现类中实现抽象方法 |
| 构造器 | 可以有构造器 | 没有构造器 |
| 设计 | is-a关系 | can-do关系 |
内部类
定义:内部类就是在某个类的内部又定义了一个类。
实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33class Outer{
private String index="The String is in Outer Class";
public class Inner {
String index="The String is in Inner Class";
void print(){
String index="The String is in print Method";
System.out.println(index);
System.out.println(this.index);
System.out.println(Outer.this.index);
}
}//内部类Inner定义
void print(){
Inner inner = new Inner();
inner.print();
}
Inner getInner(){
return new Inner();
}}
public class TestOuterAndInner{
{
Outer outer = new Outer(); //先产生外部类对象
//利用外部类对象引用.new语句创建内部类对象实例
Outer.Inner inner = outer.new Inner();
//利用外部类提供的getter方法创建内部类对象实例
//Outer.Inner inner = outer.getInner();
inner.print();
}
}
第七章 异常
异常分类
Error:致命异常。需人工介入(虚拟机产生的错误:StackOverflowError、OutOfMemoryError)Exception:非致命异常。
异常处理
- 声明抛出处理:向调用方传播异常
- 显式声明抛出:
throws语句 - 隐式声明抛出:
throws语句可省略
- 显式声明抛出:
- 程序捕获处理:在当前方法捕获处理异常
- 非嵌套:
try/catch/finally语句 - 嵌套:同上
- 非嵌套:
- 声明抛出处理:向调用方传播异常
第八章 字符串——string
string对象的构造与初始化1
2
3
4
5
6
7
8
9
10
11
12String s1 = "abc";
String s3 = "abc";
String s2 = new String(“abc");
String s4 = new String(“abc");
//“==”用于比较两个对象的引用是否相同
System.out.println(s1==s2); // false
System.out.println(s1==s3); // true
System.out.println(s2==s4); // false
// String对equals方法进行了覆写,可用于比较两个字符串的内容是否相同。
System.out.println(s1.equals(s3)); // true
System.out.println(s2.equals(s4)); // trueString对象的特点String对象是不可变的,在String类中每一个看起来会修改String对象内容的方法,实质都是创建了一个全新的String对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char[] value; //常量字符数组对象引用
public String concat(String str) {//字符串连接
int otherLen = str.length();
if (otherLen == 0) {
return this;//返回当前对象
}
int len = value.length;
char[] buf = Arrays.copyOf(value, len + otherLen);//拷贝之前的
str.getChars(buf, len);//连接现在的
return new String(buf, true); //创建新的对象
}StringBuffer:StringBuffer对象的值是可变的,对字符串的增加、插入、修改、删除等操作比String高效(不需多次创建新的对象)。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//StringBuffer源码
public final class StringBuffer extends AbstractStringBuilder
implements java.io.Serializable, CharSequence {
//AbstractStringBuilder源码
abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
char[] value; //普通字符数组对象引用,被StringBuffer继承
//AbstractStringBuilder源码
public AbstractStringBuilder append(String str) {
if (str == null)
return appendNull();
int len = str.length();
ensureCapacityInternal(count + len); //有可能扩容,产生新数组
str.getChars(0, len, value, count);
count += len;
return this;
}
//StringBuffer 源码
public synchronized StringBuffer append(String str) {
toStringCache = null;
super.append(str); //调用父类的append方法
return this; //返回当前对象引用
}StringBUilder: JDK5 引入了StringBuilder,其与StringBuffer的 API兼容,性能比StringBuffer更高,但不是线程安全的。
1
2
3
4
5
6
7
8
9
10
11
12
13//String字符串拼接:
String s = "a";
for(int i=0; i<10000;i++){
s = s + “b” ; //编译器会进行优化,但此种写法仍然效率低下,循环体内每次
需要产生StringBuilder对象
//StringBuilder字符串拼接:
StringBuilder st = new StringBuilder("a"); //效率较高,只需新建一个对象
for(int i=0; i<10000;i++){
st.append(“b");
}
//字符串拼接,应使用StringBuilder或StringBuffer,并将对象创建语句放到循环体外String类的常用方法及源码学习string类的设计优点及使用场景
线程
创建线程—— Thread类
1 | public class Thread extends Object implements Runnable |
方法一:
1 | import java.util.*; |
方法二:
方法三:异步
1 | import java.util.*; |
线程安全
- 数据单线程内可见
- 只读对象
- 线程安全类
如果多个线程想要对某个对象进行并发更新操作,但又不属于上述三类,此时需要考虑线程安全问题,在代码中实现安全同步机制。
线程安全-访问共享资源问题
线程安全问题-访问共享资源-可见性
线程安全问题-访问共享资源-原子性
解决线程安全问题:线程同步机制(互斥)
- 对象监视器
- 同步块又称临界区,保证同一时间只有一个线程执行同步块内的代码
- 锁的范围尽可能小:能锁对象,就不要锁类;能锁代码块就不要锁方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32class Resource implements Runnable {
volatile public int i;
volatile public Integer it;
public Resource(int _i){
i = _i;
it = new Integer(i);
}
public void run(){
while(true){
synchronized(it){
if (i>0){
try{
Thread.sleep(200);
}
catch(Exception e){}
i--;
System.out.println(Thread.currentThread().getName()+" "+i);
}
else{
System.out.println(Thread.currentThread().getName());
break; }}
}}}
public class TestSecurity{
public static void main(String[] args){
Resource m = new Resource(9);
Thread t1 = new Thread(m);
Thread t2 = new Thread(m);
t1.start();
t2.start();
}
}Java并发包中的锁类
死锁问题(dead lock)
如果多个线程都处于等待状态,彼此需要对方所占用的监视器所有权,就构成死锁,Java即不能发现也不能避免死锁。


- 对象监视器
线程同步通信(协作)
第十章 I/O输入输出
流的分类
字节流与字符流
