-
Notifications
You must be signed in to change notification settings - Fork 5
/
java.txt
4746 lines (3375 loc) · 224 KB
/
java.txt
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1.2 什么是计算机 2
1.2.1 中央处理器 2
1.2.2 比特和字节 3
1.2.3 内存 3
1.2.4 存储设备 4
1.2.5 输入和输出设备 4
1.2.6 通信设备 5
1.3 编程语言 6
1.3.1 机器语言 6
1.3.2 汇编语言 6
1.3.3 高级语言 7
1.4 操作系统 8
1.4.1 控制和监视系统活动 8
1.4.2 分配和调配系统资源 8
1.4.3 调度操作 8
1.5 Java、万维网以及其他 9
1.6 Java语言规范、API、JDK、JRE和IDE 10
1.7 一个简单的Java程序 11
1.8 创建、编译和执行Java程序 13
1.9 程序设计风格和文档 16
1.9.1 正确的注释和注释风格 16
1.9.2 正确的缩进和空白 16
1.9.3 块的风格 17
1.10 程序设计错误 17
1.10.1 语法错误 17
1.10.2 运行时错误 18
1.10.3 逻辑错误 19
1.10.4 常见错误 19
1.11 使用NetBeans开发Java程序 20
1.11.1 创建Java工程 21
1.11.2 创建Java类 22
1.11.3 编译和运行类 22
1.12 使用Eclipse开发Java程序 23
1.12.1 创建Java工程 23
1.12.2 创建Java类 24
1.12.3 编译和运行类 24
关键术语 25
本章小结 26
测试题 27
编程练习题 27
第2章 基本程序设计 29
2.1 引言 29
2.2 编写简单的程序 29
2.3 从控制台读取输入 32
2.4 标识符 35
2.5 变量 35
2.6 赋值语句和赋值表达式 37
2.7 命名常量 38
2.8 命名习惯 39
2.9 数值数据类型和操作 39
2.9.1 数值类型 39
2.9.2 从键盘读取数值 40
2.9.3 数值操作符 40
2.9.4 幂运算 42
2.10 数值型字面值 43
2.10.1 整型字面值 43
2.10.2 浮点型字面值 43
2.10.3 科学记数法 44
2.11 表达式求值以及操作符优先级 44
2.12 示例学习:显示当前时间 45
2.13 增强赋值操作符 47
2.14 自增和自减操作符 48
2.15 数值类型转换 50
2.16 软件开发过程 52
2.17 示例学习:整钱兑零 55
2.18 常见错误和陷阱 57
关键术语 59
本章小结 60
测试题 60
编程练习题 60
第3章 选择 65
3.1 引言 65
3.2 boolean数据类型 65
3.3 if语句 67
3.4 双分支if-else语句 69
3.5 嵌套的if语句和多分支if-else语句 70
3.6 常见错误和陷阱 72
3.7 产生随机数 75
3.8 示例学习:计算身体质量指数 77
3.9 示例学习:计算税率 78
3.10 逻辑操作符 81
3.11 示例学习:判定闰年 84
3.12 示例学习:彩票 85
3.13 switch语句 87
3.14 条件操作 90
3.15 操作符的优先级和结合规则 91
3.16 调试 92
关键术语 93
本章小结 93
测试题 94
编程练习题 94
第4章 数学函数、字符和字符串 102
4.1 引言 102
4.2 常用数学函数 103
4.2.1 三角函数方法 103
4.2.2 指数函数方法 103
4.2.3 取整方法 104
4.2.4 min、max和abs方法 104
4.2.5 random方法 105
4.2.6 示例学习:计算三角形的角度 105
4.3 字符数据类型和操作 107
4.3.1 Unicode和ASCII码 107
4.3.2 特殊字符的转义序列 108
4.3.3 字符型数据与数值型数据之间的转换 108
4.3.4 字符的比较和测试 109
4.4 String类型 111
4.4.1 获取字符串长度 112
4.4.2 从字符串中获取字符 112
4.4.3 连接字符串 113
4.4.4 字符串的转换 113
4.4.5 从控制台读取字符串 114
4.4.6 从控制台读取字符 114
4.4.7 字符串比较 115
4.4.8 获得子字符串 116
4.4.9 获取字符串中的字符或者子串 117
4.4.10 字符串和数字间的转换 118
4.5 示例学习 120
4.5.1 猜测生日 120
4.5.2 将十六进制数转换为十进制数 123
4.5.3 使用字符串修改彩票程序 124
4.6 格式化控制台输出 126
关键术语 129
本章小结 129
测试题 130
编程练习题 130
第5章 循环 136
5.1 引言 136
5.2 while循环 137
5.3 示例学习:猜数字 139
5.4 循环设计策略 142
5.5 使用用户确认或者标记值控制循环 144
5.6 do-while循环 146
5.7 for循环 148
5.8 采用哪种循环 151
5.9 嵌套循环 153
5.10 最小化数值错误 155
5.11 示例学习 156
5.11.1 求最大公约数 156
5.11.2 预测未来学费 158
5.11.3 将十进制数转换为十六进制数 158
5.12 关键字break和continue 160
5.13 示例学习:判断回文 163
5.14 示例学习:显示素数 164
关键术语 167
本章小结 167
测试题 167
编程练习题 167
第6章 方法 176
6.1 引言 176
6.2 定义方法 177
6.3 调用方法 178
6.4 void方法与返回值方法 180
6.5 按值传参 183
6.6 模块化代码 186
6.7 示例学习:将十六进制数转换为十进制数 188
6.8 重载方法 190
6.9 变量的作用域 192
6.10 示例学习:生成随机字符 193
6.11 方法抽象和逐步求精 195
6.11.1 自顶向下的设计 196
6.11.2 自顶向下和自底向上的实现 197
6.11.3 实现细节 199
6.11.4 逐步求精的优势 201
关键术语 202
本章小结 202
测试题 203
编程练习题 203
第7章 一维数组 212
7.1 引言 212
7.2 数组的基础知识 212
7.2.1 声明数组变量 213
7.2.2 创建数组 213
7.2.3 数组大小和默认值 214
7.2.4 访问数组元素 214
7.2.5 数组初始化简写方式 215
7.2.6 处理数组 215
7.2.7 foreach循环 217
7.3 示例学习:分析数字 219
7.4 示例学习:一副牌 220
7.5 复制数组 222
7.6 将数组传递给方法 223
7.7 方法返回数组 226
7.8 示例学习:统计每个字母出现的次数 226
7.9 可变长参数列表 230
7.10 数组的查找 230
7.10.1 线性查找法 231
7.10.2 二分查找法 231
7.11 数组的排序 234
7.12 Arrays类 235
7.13 命令行参数 237
7.13.1 向main方法传递字符串 237
7.13.2 示例学习:计算器 238
关键术语 239
本章小结 240
测试题 240
编程练习题 240
第8章 多维数组 248
8.1 引言 248
8.2 二维数组基础 248
8.2.1 声明二维数组变量并创建二维数组 249
8.2.2 获取二维数组的长度 250
8.2.3 不规则数组 250
8.3 处理二维数组 251
8.4 将二维数组传递给方法 253
8.5 示例学习:多选题测验评分 254
8.6 示例学习:找出距离最近的点对 255
8.7 示例学习:数独 257
8.8 多维数组 260
8.8.1 示例学习:每日温度和湿度 261
8.8.2 示例学习:猜生日 263
本章小结 264
测试题 264
编程练习题 264
第9章 对象和类 276
9.1 引言 276
9.2 为对象定义类 277
9.3 示例:定义类和创建对象 278
9.4 使用构造方法构造对象 283
9.5 通过引用变量访问对象 284
9.5.1 引用变量和引用类型 284
9.5.2 访问对象的数据和方法 285
9.5.3 引用数据域和null值 285
9.5.4 基本类型变量和引用类型变量的区别 286
9.6 使用Java库中的类 288
9.6.1 Date类 288
9.6.2 Random类 289
9.6.3 Point2D类 289
9.7 静态变量、常量和方法 291
9.8 可见性修饰符 296
9.9 数据域封装 297
9.10 向方法传递对象参数 300
9.11 对象数组 303
9.12 不可变对象和类 305
9.13 变量的作用域 307
9.14 this引用 308
9.14.1 使用this引用数据域 308
9.14.2 使用this调用构造方法 309
关键术语 310
本章小结 311
测试题 311
编程练习题 311
第10章 面向对象思考 316
10.1 引言 316
10.2 类的抽象和封装 316
10.3 面向对象的思想 320
10.4 类的关系 322
10.4.1 关联 323
10.4.2 聚集和组合 324
10.5 示例学习:设计Course类 325
10.6 示例学习:设计栈类 327
10.7 将基本数据类型值作为对象处理 329
10.8 基本类型和包装类类型之间的自动转换 332
10.9 BigInteger和BigDecimal类 333
10.10 String类 334
10.10.1 构造字符串 335
10.10.2 不可变字符串与驻留字符串 335
10.10.3 替换和拆分字符串 336
10.10.4 使用模式匹配、替换和拆分 336
10.10.5 字符串与数组之间的转换 337
10.10.6 将字符和数值转换成字符串 338
10.10.7 格式化字符串 338
10.11 StringBuilder类和StringBuffer类 340
10.11.1 修改StringBuilder中的字符串 341
10.11.2 toString、capacity、length、setLength和charAt方法 343
10.11.3 示例学习:判断回文串时忽略既非字母又非数字的字符 343
关键术语 346
本章小结 346
测试题 346
编程练习题 346
第11章 继承和多态 354
11.1 引言 354
11.2 父类和子类 354
11.3 使用super关键字 360
11.3.1 调用父类的构造方法 360
11.3.2 构造方法链 361
11.3.3 调用父类的普通方法 362
11.4 方法重写 363
11.5 方法重写与重载 364
11.6 Object类及其toString()方法 366
11.7 多态 366
11.8 动态绑定 367
11.9 对象转换和instanceof操作符 370
11.10 Object类的equals方法 374
11.11 ArrayList类 375
11.12 关于列表的一些有用方法 381
11.13 示例学习:自定义栈类 382
11.14 protected数据和方法 383
11.15 防止继承和
第19章 泛型
19.1 引言
19.2 动机和优点
19.3 定义泛型类和接口
19.4 泛型方法
19.5 示例学习:对一个对象数组进行排序
19.6 原生类型和向后兼容
19.7 通配泛型
19.8 泛型的擦除和限制
19.9 示例学习:泛型矩阵类
关键术语
本章小结
测试题
编程练习题
第20章 线性表、栈、队列和优先队列
20.1 引言
20.2 集合
20.3 迭代器
20.4 使用forEach方法
20.5 线性表
20.5.1 11st接口中的通用方法
20.5.2 数组线性表类ArrayList和链表类L1nkedLlst
20.6 Comparator接口
20.7 线性表和集合的静态方法
20.8 示例学习:弹球
20.9 向量类和栈类
20.10 队列和优先队列
20.10.1 Queue接口
20.10.2 双端队列Deque和链表LinkedList
20.11 示例学习:表达式求值
关键术语
本章小结
测试题
编程练刁题
第21章 规则集和映射
21.1 引言
21.2 规则集
21.2.1 HashSet
21.2.2 LinkedHashSet
21.2.3 TreeSet
21.3 比较规则集和线性表的性能
21.4 不例学习:关键字计数
21.5 映射
21.6 示例学习:单词的出现次数
21.7 单元素与不可变的
集合和映射
关键术语
本章小结
测试题
编程练习题
第22章 开发高效算法
22.1 引言
22.2 使用大D标记来衡量算法效率
22.3 示例:确定大D
22.4 分析算法的时间复杂度
22.4.1 分析二分查找算法
22.4.2 分析选择排序算法
22.4.3 分析汉诺塔问题
22.4.4 常用的递推关系
22.4.5 比较常用的增长函数
22.5 使用动态编程寻找斐波那契数
22.6 使用欧几里得算法求最大公约数
22.7 寻找素数的高效算法
22.8 使用分而治之法寻找最近点对
22.9 使用回溯法解决八皇后问题
22.10 计算几何:寻找凸包
22.10.1 卷包裹算法
22.10.2 格雷厄姆算法
关键术语
本章小结
测试题
编程练习题
第23章 排序
第24章 实现线性表、栈、队列和优先队列
第25章 二叉搜索树
第26章 AVL树
第27章 散列
第28章 图及其应用
第29章 加权图及其应用
第30章 集合流的聚合操作
第2章 创建和销毁对象 4
第1条:用静态工厂方法代替构造器 4
第2条:遇到多个构造器参数时要考虑使用构建器 8
第3条:用私有构造器或者枚举类型强化Singleton属性 13
public enum StatusCodeEnum {
// 基础状态码
SUCCESS(100200, "操作成功"),
FAIL(100201, "接口调用失败"),
EXCEPTION(100501, "操作失败,请联系管理员"),
PARAM_ERROR(100202, "请求参数为空"),
//版本管理
TASKNAME_ERROR(101202, "该任务字段名已存在"),
RUNTASK_ERROR(101203, "任务正在执行"),
RELOADTASK_ERROR(101204, "任务重跑失败,有上层关联任务正在执行"),
TASK_NOT_EXIST_ERROR(101205, "任务信息不存在"),
//流程控制
TASK_NAME_ERROR(102201,"该任务名错误;"),
RUN_TASK_ERROR(102202,"任务正在执行;"),
PROC_DATA_ERROR(102203,"执行数据版本频率字段procData,配置错误;");
private int code;
private String msg;
StatusCodeEnum(int code, String msg){
this.code = code;
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
第4条:通过私有构造器强化不可实例化的能力 15
第5条:优先考虑依赖注入来引用资源 16
第6条:避免创建不必要的对象 18
第7条:消除过期的对象引用 20
第8条:避免使用终结方法和清除方法 23
第9条:try-with-resources优先于try-f?inally 27
第3章 对于所有对象都通用的方法 30
第10条:覆盖equals时请遵守通用约定 30
第11条:覆盖equals时总要覆盖hashCode 40
第12条:始终要覆盖toString 44
第13条:谨慎地覆盖clone 46
第14条:考虑实现Comparable接口 53
第4章 类和接口 59
第15条:使类和成员的可访问性最小化 59
第16条:要在公有类而非公有域中使用访问方法 62
第17条:使可变性最小化 64
第18条:复合优先于继承 70
第19条:要么设计继承并提供文档说明,要么禁止继承 75
第20条:接口优于抽象类 79
第21条:为后代设计接口 83
第22条:接口只用于定义类型 85
第23条:类层次优于标签类 86
第24条:静态成员类优于非静态成员类 88
第25条:限制源文件为单个顶级类 91
第5章 泛型 93
第26条:请不要使用原生态类型 93
第27条:消除非受检的警告 97
第28条:列表优于数组 99
第29条:优先考虑泛型 102
第30条:优先考虑泛型方法 106
第31条:利用有限制通配符来提升API的灵活性 109
第32条:谨慎并用泛型和可变参数 114
第33条:优先考虑类型安全的异构容器 118
第6章 枚举和注解 123
第34条:用enum代替int常量 123
第35条:用实例域代替序数 131
第36条:用EnumSet代替位域 132
第37条:用EnumMap代替序数索引 134
第38条:用接口模拟可扩展的枚举 138
第39条:注解优先于命名模式 140
第40条:坚持使用Override注解 147
第41条:用标记接口定义类型 149
第7章 Lambda和Stream 151
第42条:Lambda优先于匿名类 151
第43条:方法引用优先于Lambda 154
第44条:坚持使用标准的函数接口 156
第45条:谨慎使用Stream 159
第46条:优先选择Stream中无副作用的函数 164
第47条:Stream要优先用Collection作为返回类型 168
第48条:谨慎使用Stream并行 172
第8章 方法 176
第49条:检查参数的有效性 176
第50条:必要时进行保护性拷贝 179
第51条:谨慎设计方法签名 182
第52条:慎用重载 184
第53条:慎用可变参数 189
第54条:返回零长度的数组或者集合,而不是null 190
第55条:谨慎返回optinal 192
第56条:为所有导出的API元素编写文档注释 196
第9章 通用编程 202
第57条:将局部变量的作用域最小化 202
第58条:for-each循环优先于传统的for循环 204
第59条:了解和使用类库 207
第60条:如果需要精确的答案,请避免使用f?loat和double 209
第61条:基本类型优先于装箱基本类型 211
第62条:如果其他类型更适合,则尽量避免使用字符串 213
第63条:了解字符串连接的性能 215
第64条:通过接口引用对象 216
第65条:接口优先于反射机制 218
第66条:谨慎地使用本地方法 220
第67条:谨慎地进行优化 221
第68条:遵守普遍接受的命名惯例 223
第10章 异常 227
第69条:只针对异常的情况才使用异常 227
第70条:对可恢复的情况使用受检异常,对编程错误使用运行时异常 229
第71条:避免不必要地使用受检异常 231
第72条:优先使用标准的异常 232
第73条:抛出与抽象对应的异常 234
第74条:每个方法抛出的所有异常都要建立文档 235
第75条:在细节消息中包含失败-捕获信息 237
第76条:努力使失败保持原子性 238
第77条:不要忽略异常 239
第11章 并发 241
第78条:同步访问共享的可变数据 241
第79条:避免过度同步 245
第80条:executor、task和stream优先于线程 250
第81条:并发工具优先于wait和notify 251
第82条:线程安全性的文档化 256
第83条:慎用延迟初始化 258
第84条:不要依赖于线程调度器 261
第12章 序列化 263
第85条:其他方法优先于Java序列化 263
第86条:谨慎地实现Serializable接口 266
第87条:考虑使用自定义的序列化形式 269
第88条:保护性地编写readObject方法 274
第89条:对于实例控制,枚举类型优先于readResolve 279
第90条:考虑用序列化代理代替序列化实例 282
附录 与第2版中条目的对应关系 286
Chapter 1:Big Data Analytics with Java
Why data analytics on big data?
Big data for analytics
Big data - a bigger pay package for Java developers
Basics of Hadoop - a Java sub-project
Distributed computing on Hadoop
HDFS concepts
Design and architecture of HDFS
Main components of HDFS
HDFS simple commands
Apache Spark
Concepts
Transformations
Actions
Spark Java API
Spark samples using Java 8
Loading data
Data operations - cleansing and munging
Analyzing data - count, projection, grouping, aggregation, and max/min
Actions on RDDs
Paired RDDs
Saving data
Collecting and printing results
Executing Spark programs on Hadoop
Apache Spark sub-projects
Spark machine learning modules
Mahout - a popular Java ML library
Deeplearning4j - a deep learning library
Summary
Chapter 2: First Steps in Data Analysis
Datasets
Data cleaning and munging
Basic analysis of data with Spark SQL
Building SparkConf and context
Dataframe and datasets
Load and parse data
Analyzing data - the Spark-SQL way
Spark SQL for data exploration and analytics
Market basket analysis - Apriori algorithm
Implementation of the Apriori algorithm in Apache Spark
Efficient market basket analysis using FP-Growth algorithm
Running FP-Growth on Apache Spark
Summary
Chapter 3: Data Visualization
Data visualization with Java JFreeChart
Using charts in big data analytics
Time Series chart
All India seasonal and annual average temperature series dataset
Simple single Time Series chart
第1章 计算机与Java引论 1
1.1 计算机基础 1
1.1.1 硬件与内存 2
1.1.2 程序 3
1.1.3 编程语言、编译器和解释器 4
1.1.4 Java字节码 5
1.1.5 类加载器 7
1.2 浅尝Java 8
1.2.1 Java语言的历史 8
1.2.2 应用程序与小应用程序 9
1.2.3 第一个Java应用程序 9
1.2.4 编写、编译和运行Java程序 13
1.3 编程基础 14
1.3.1 面向对象编程 14
1.3.2 算法 17
1.3.3 测试与调试 18
1.3.4 软件复用 19
1.4 图形化编程补充读物 20
1.4.1 一个JavaFX应用程序样例 21
1.4.2 图形的尺寸和位置 23
1.4.3 绘制椭圆和圆 24
1.4.4 绘制弧 25
本章小结 27
练习 28
实践程序 29
编程项目 29
自测问题答案 30
第2章 基本的计算 33
2.1 变量和表达式 33
2.1.1 变量 33
2.1.2 数据类型 35
2.1.3 Java标识符 37
2.1.4 赋值语句 38
2.1.5 简单输入 40
2.1.6 简单屏幕输出 41
2.1.7 常量 42
2.1.8 具名常量 43
2.1.9 赋值兼容性 44
2.1.10 类型强制转换 45
2.1.11 算术运算 48
2.1.12 括号和优先级规则 50
2.1.13 特殊赋值操作符 51
2.1.14 案例研究:售货机找零 52
2.1.15 递增和递减操作符 56
2.1.16 更多有关递增和递减操作符的讨论 57
2.2 String类 57
2.2.1 字符串常量和变量 58
2.2.2 字符串连接 58
2.2.3 字符串方法 59
2.2.4 字符串处理 62
2.2.5 转义字符 63
2.2.6 Unicode字符集 64
2.3 键盘和屏幕I/O 65
2.3.1 屏幕输出 65
2.3.2 键盘输入 67
2.3.3 其他输入界定符(选修) 72
2.3.4 使用printf的格式化输出(选修) 73
2.4 文档和样式 75
2.4.1 有意义的变量名 75
2.4.2 注释 75
2.4.3 缩进 77
2.4.4 使用具名常量 78
2.5 图形化编程补充读物 80
2.5.1 将样式规则应用于JavaFX应用程序 80
2.5.2 介绍JOptionPane类 81
2.5.3 将输入作为其他数字类型读取 87
2.5.4 编程示例:具有窗口化I/O的找零程序 88
本章小结 90
练习 90
实践程序 92
编程项目 93
自测问题答案 94
第3章 流控制—分支 98
3.1 if-else语句 98
3.1.1 基本的if-else语句 98
3.1.2 布尔表达式 104
3.1.3 比较字符串 107
3.1.4 嵌套的if-else语句 111
3.1.5 多重分支的if-else语句 112
3.1.6 编程示例:给出字母等第 114
3.1.7 案例研究:体重指数 116
3.1.8 条件操作符(选修) 118
3.1.9 exit方法 119
3.2 boolean类型 120
3.2.1 布尔变量 120
3.2.2 优先级规则 121
3.2.3 布尔值的输入和输出 123
3.3 switch语句 124
3.4 图形化编程补充读物 130
3.4.1 指定绘图颜色 131
3.4.2 Yes或No问题的对话框 134
本章小结 135
练习 136
实践程序 137
编程项目 138
自测问题答案 140
第4章 流控制—循环 142
4.1 Java循环语句 142
4.1.1 while语句 143
4.1.2 do-while语句 146
4.1.3 编程示例:臭虫侵扰 149
4.1.4 编程示例:嵌套循环 154
4.1.5 for语句 155
4.1.6 在for语句中声明变量 160
4.1.7 在for语句中使用逗号(选修) 160
4.1.8 for-each语句 162
4.2 用循环编程 162
4.2.1 循环体 162
4.2.2 初始化语句 163
4.2.3 控制循环迭代次数 164
4.2.4 案例研究:使用布尔变量来终止循环 166
4.2.5 编程示例:消费热潮 168
4.2.6 循环中的break语句和continue语句(选修) 170
4.2.7 循环缺陷 172
4.2.8 跟踪变量 174
4.2.9 断言检查 175
4.3 图形化编程补充读物 177
4.3.1 编程示例:一个包含多张脸的JavaFX应用程序 177
4.3.2 绘制文本 181
本章小结 182
练习 182
实践程序 184
编程项目 185
自测问题答案 188
第5章 定义类和方法 193
5.1 类和方法定义 193
5.1.1 类文件和单独编译 195
5.1.2 编程示例:实现Dog类 195
5.1.3 实例变量 196
5.1.4 方法 198
5.1.5 定义void方法 200
5.1.6 定义有返回值的方法 201
5.1.7 编程示例:实现Species类的第一次尝试 205
5.1.8 关键词this 208
5.1.9 局部变量 209
5.1.10 块 211
5.1.11 基本类型参数 212
5.2 信息隐藏和封装 216
5.2.1 信息隐藏 217
5.2.2 前置条件和后置条件注释 217
5.2.3 public和private修饰符 218
5.2.4 编程示例:为什么实例变量应该是私有的 220
5.2.5 编程示例:矩形类的另一种实现 221
5.2.6 访问器方法和修改器方法 223
5.2.7 编程示例:Purchase类 225
5.2.8 调用方法的方法 228
5.2.9 封装 233
5.2.10 使用javadoc自动归档 235
5.2.11 UML类图 235
5.3 对象和引用 236
5.3.1 类类型变量 237
5.3.2 定义类的equals方法 242
5.3.3 编程示例:Species类 244
5.3.4 布尔值方法 246
5.3.5 案例研究:单元测试 247
5.3.6 类类型参数 249
5.3.7 编程示例:类类型参数与
========
Java 中的注解是如何工作的?
什么是注解?
为什么要引入注解?
Annotation是如何工作的?怎么编写自定义的Annotation?
注解用例
ADF (应用程序框架)和注解
自Java5.0版本引入注解之后,它就成为了Java平台中非常重要的一部分。开发过程中,我们也时常在应用代码中会看到诸如@Override,@Deprecated这样的注解。这篇文章中,我将向大家讲述到底什么是注解,为什么要引入注解,注解是如何工作的,如何编写自定义的注解(通过例子),什么情况下可以使用注解以及最新注解和ADF(应用开发框架)。这会花点儿时间,所以为自己准备一杯咖啡,让我们来进入注解的世界吧。
java-annotations
java-annotations
什么是注解?
用一个词就可以描述注解,那就是元数据,即一种描述数据的数据。所以,可以说注解就是源代码的元数据。比如,下面这段代码:
img
img
上面的代码中,我重写了toString()方法并使用了@Override注解。但是,即使我不使用@Override注解标记代码,程序也能够正常执行。那么,该注解表示什么?这么写有什么好处吗?事实上,@Override告诉编译器这个方法是一个重写方法(描述方法的元数据),如果父类中不存在该方法,编译器便会报错,提示该方法没有重写父类中的方法。如果我不小心拼写错误,例如将toString()写成了toStrring(){double r},而且我也没有使用@Override注解,那程序依然能编译运行。但运行结果会和我期望的大不相同。现在我们了解了什么是注解,并且使用注解有助于阅读程序。
Annotation是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符。它是一种由JSR-175标准选择用来描述元数据的一种工具。
为什么要引入注解?
使用Annotation之前(甚至在使用之后),XML被广泛的应用于描述元数据。不知何时开始一些应用开发人员和架构师发现XML的维护越来越糟糕了。他们希望使用一些和代码紧耦合的东西,而不是像XML那样和代码是松耦合的(在某些情况下甚至是完全分离的)代码描述。如果你在Google中搜索“XML vs. annotations”,会看到许多关于这个问题的辩论。最有趣的是XML配置其实就是为了分离代码和配置而引入的。上述两种观点可能会让你很疑惑,两者观点似乎构成了一种循环,但各有利弊。下面我们通过一个例子来理解这两者的区别。
假如你想为应用设置很多的常量或参数,这种情况下,XML是一个很好的选择,因为它不会同特定的代码相连。如果你想把某个方法声明为服务,那么使用Annotation会更好一些,因为这种情况下需要注解和方法紧密耦合起来,开发人员也必须认识到这点。
另一个很重要的因素是Annotation定义了一种标准的描述元数据的方式。在这之前,开发人员通常使用他们自己的方式定义元数据。例如,使用标记interfaces,注释,transient关键字等等。每个程序员按照自己的方式定义元数据,而不像Annotation这种标准的方式。
目前,许多框架将XML和Annotation两种方式结合使用,平衡两者之间的利弊。
Annotation是如何工作的?怎么编写自定义的Annotation?
在讲述这部分之前,建议你首先下载Annotation的示例代码AnnotationsSample.zip 。下载之后放在你习惯使用的IDE中,这些代码会帮助你更好的理解Annotation机制。
编写Annotation非常简单,可以将Annotation的定义同接口的定义进行比较。我们来看两个例子:一个是标准的注解@Override,另一个是用户自定义注解@Todo。
img
img
对于@Override注释你可能有些疑问,它什么都没做,那它是如何检查在父类中有一个同名的函数呢。当然,不要惊讶,我是逗你玩的。@Override注解的定义不仅仅只有这么一点代码。这部分内容很重要,我不得不再次重复:Annotations仅仅是元数据,和业务逻辑无关。理解起来有点困难,但就是这样。如果Annotations不包含业务逻辑,那么必须有人来实现这些逻辑。元数据的用户来做这个事情。Annotations仅仅提供它定义的属性(类/方法/包/域)的信息。Annotations的用户(同样是一些代码)来读取这些信息并实现必要的逻辑。
当我们使用Java的标注Annotations(例如@Override)时,JVM就是一个用户,它在字节码层面工作。到这里,应用开发人员还不能控制也不能使用自定义的注解。因此,我们讲解一下如何编写自定义的Annotations。
我们来逐个讲述编写自定义Annotations的要点。上面的例子中,你看到一些注解应用在注解上。
J2SE5.0版本在 java.lang.annotation提供了四种元注解,专门注解其他的注解:
@Documented –注解是否将包含在JavaDoc中@Retention –什么时候使用该注解@Target? –注解用于什么地方@Inherited – 是否允许子类继承该注解
@Documented–一个简单的Annotations标记注解,表示是否将注解信息添加在java文档中。
@Retention– 定义该注解的生命周期。
RetentionPolicy.SOURCE – 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
RetentionPolicy.CLASS – 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
RetentionPolicy.RUNTIME– 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
@Target – 表示该注解用于什么地方。如果不明确指出,该注解可以放在任何地方。以下是一些可用的参数。需要说明的是:属性的注解是兼容的,如果你想给7个属性都添加注解,仅仅排除一个属性,那么你需要在定义target包含所有的属性。
ElementType.TYPE:用于描述类、接口或enum声明ElementType.FIELD:用于描述实例变量ElementType.METHODElementType.PARAMETERElementType.CONSTRUCTORElementType.LOCAL_VARIABLEElementType.ANNOTATION_TYPE 另一个注释ElementType.PACKAGE 用于记录java文件的package信息
@Inherited – 定义该注释和子类的关系
那么,注解的内部到底是如何定义的呢?Annotations只支持基本类型、String及枚举类型。注释中所有的属性被定义成方法,并允许提供默认值。
img
img
下面的例子演示了如何使用上面的注解。
img
img
如果注解中只有一个属性,可以直接命名为“value”,使用时无需再标明属性名。
img
img
但目前为止一切看起来都还不错。我们定义了自己的注解并将其应用在业务逻辑的方法上。现在我们需要写一个用户程序调用我们的注解。这里我们需要使用反射机制。如果你熟悉反射代码,就会知道反射可以提供类名、方法和实例变量对象。所有这些对象都有getAnnotation()这个方法用来返回注解信息。我们需要把这个对象转换为我们自定义的注释(使用 instanceOf()检查之后),同时也可以调用自定义注释里面的方法。看看以下的实例代码,使用了上面的注解:
img
img
注解用例
注解的功能很强大,Spring和Hebernate这些框架在日志和有效性中大量使用了注解功能。注解可以应用在使用标记接口的地方。不同的是标记接口用来定义完整的类,但你可以为单个的方法定义注释,例如是否将一个方法暴露为服务。
在最新的servlet3.0中引入了很多新的注解,尤其是和servlet安全相关的注解。
HandlesTypes –该注解用来表示一组传递给ServletContainerInitializer的应用类。
HttpConstraint – 该注解代表所有HTTP方法的应用请求的安全约束,和ServletSecurity注释中定义的HttpMethodConstraint安全约束不同。
HttpMethodConstraint – 指明不同类型请求的安全约束,和ServletSecurity 注解中描述HTTP协议方法类型的注释不同。
MultipartConfig –该注解标注在Servlet上面,表示该Servlet希望处理的请求的 MIME 类型是 multipart/form-data。
ServletSecurity 该注解标注在Servlet继承类上面,强制该HTTP协议请求遵循安全约束。
WebFilter – 该注解用来声明一个Server过滤器;
WebInitParam – 该注解用来声明Servlet或是过滤器的中的初始化参数,通常配合 @WebServlet 或者 @WebFilter 使用。
WebListener –该注解为Web应用程序上下文中不同类型的事件声明监听器。
WebServlet –该注解用来声明一个Servlet的配置。
ADF (应用程序框架)和注解
现在我们开始讨论文章的最后一部分了。应用程序框架,被称为ADF,由Oracle开发用来创建Oracle融合应用。我们已经了解了注解的优缺点,也知道如何编写自定义的注解,但我们应该将注解应用在ADF的哪部分呢?ADF是否提供了一些朴素的注解?很好的问题,确实在ADF中大量使用注解有一些限制。之前提到的应用框架如Spring和Hibernate使用AOP(面向侧面的程序设计)。在AOP中,框架提供了一种机制,在事件的预处理和后续处理中注入代码。例如:你有一个钩子用来在方法执行之前和之后添加代码,所以你可以在这些地方编写你的用户代码。ADF不使用AOP。如果我们有任何注解的用例可用,我们可能需要通过继承的方式实现。
=====================================================================
不了解这12个语法糖,别说你会Java!
语法糖
语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。简而言之,语法糖让程序更加简洁,有更高的可读性。
有意思的是,在编程领域,除了语法糖,还有语法盐和语法糖精的说法,篇幅有限这里不做扩展了。
我们所熟知的编程语言中几乎都有语法糖。作者认为,语法糖的多少是评判一个语言够不够牛逼的标准之一。
很多人说Java是一个“低糖语言”,其实从Java 7开始Java语言层面上一直在添加各种糖,主要是在“Project Coin”项目下研发。尽管现在Java有人还是认为现在的Java是低糖,未来还会持续向着“高糖”的方向发展。
解语法糖
前面提到过,语法糖的存在主要是方便开发人员使用。但其实,Java虚拟机并不支持这些语法糖。这些语法糖在编译阶段就会被还原成简单的基础语法结构,这个过程就是解语法糖。
说到编译,大家肯定都知道,Java语言中,javac命令可以将后缀名为.java的源文件编译为后缀名为.class的可以运行于Java虚拟机的字节码。
如果你去看com.sun.tools.javac.main.JavaCompiler的源码,你会发现在compile()中有一个步骤就是调用desugar(),这个方法就是负责解语法糖的实现的。
Java 中最常用的语法糖主要有泛型、变长参数、条件编译、自动拆装箱、内部类等。本文主要来分析下这些语法糖背后的原理。一步一步剥去糖衣,看看其本质。
糖块一、 switch 支持 String 与枚举
前面提到过,从Java 7 开始,Java语言中的语法糖在逐渐丰富,其中一个比较重要的就是Java 7中switch开始支持String。
在开始coding之前先科普下,Java中的swith自身原本就支持基本类型。比如int、char等。
对于int类型,直接进行数值的比较。对于char类型则是比较其ascii码。
所以,对于编译器来说,switch中其实只能使用整型,任何类型的比较都要转换成整型。比如byte。short,char(ackii码是整型)以及int。
那么接下来看下switch对String得支持,有以下代码:
public class switchDemoString {
public static void main(String[] args) {
String str = "world";
switch (str) {
case "hello":
System.out.println("hello");
break;
case "world":
System.out.println("world");
break;
default:
break;
}