Java编程思想

这是一个通过对《Java编程思想》(Think in java)第四版进行阅读同时对java内容查漏补缺的系列。一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会忽略或者混淆的知识点。

所列知识点全部都是针对自己个人而言,同时也欢迎大家进行补充。


第一章(对象导论)

  1. public class HelloWorld {
  2. public static void main(String[] args) {
  3. System.out.println("Hello every one,I'm cpacm");
  4. }
  5. }

这一章是java的整体介绍,让我们先熟悉了java是什么。其具体的内容都会在后面介绍。

面向基本语言的五大特性

  • 万物皆为对象。
  • 程序是对象的集合,它们通过发送消息来告知彼此所要做的。
  • 每个对象都拥有其类型。
  • 某一特定类型的所有对象都可以接收同样的消息。

第二章(一切都是对象)

一、存储

p22

栈(堆栈):存放基本类型变量和对象引用变量。位于RAM区

堆:存放new得到的对象和数组。也位于RAM区

常量存储:存放常量,包括静态变量。

二、基本类型

p26

基本数据类型在没有初始化的时候会获得一个默认值。

基本数据类型 默认值 大小
boolean false 未确定
char null 16bits
byte 0 8bits
short 0 16bits
int 0 32bits
float 0f 32bits
long 0L 64bits
double 0d 64bits

tip1:String不是基本数据类型

tip2:上面的初始默认值并不适用于方法内部变量。其默认初始化值未知。当使用未初始化的变量编译器会返回错误

  1. public class BaseType {
  2. static boolean b;
  3. static char c;
  4. static byte bt;
  5. static short s;
  6. static int i;
  7. static float f;
  8. static long l;
  9. static double d;
  10. public static void main(String[] args) {
  11. System.out.println("类变量——"+"boolean:"+b+" char:"+c+" byte:"+bt+" short:"+s+" int:"+i+" float:"+f+" long:"+l+" double:"+d);
  12. }
  13. }
  14. //类变量——boolean:false char: byte:0 short:0 int:0 float:0.0 long:0 double:0.0

第三章(操作符)

一、别名现象

p40

当两个变量包含的是同一个引用时,修改其中一个变量的值另一个变量的值也同时改变。记住new出来的对象的=赋值都是只传递引用。

Tip:减少为对象赋值。

  1. class T{
  2. int i;
  3. }
  4. public class Assigment {
  5. public static void main(String[] args) {
  6. T t1 = new T();
  7. T t2 = new T();
  8. t1.i = 5;
  9. t2.i = 8;
  10. t1 = t2;
  11. t1.i = 10000;
  12. System.out.println(t2.i);
  13. }
  14. }
  15. //10000

二、equals方法

p45

在自定义的对象中使用equals方法时需要覆盖此方法,否则默认是比较引用

三、短路

p47

其现象本质为:当已经确定一个逻辑表达式的结果时不会再计算剩余的部分。

  1. public class ShortCircuit {
  2. public static void main(String[] args) {
  3. // TODO Auto-generated method stub
  4. boolean flag1 = test1()&&test2()||test3()&&test4();
  5. System.out.println("\n");
  6. boolean flag2 = test1()&&test3()||test2()&&test4();
  7. }
  8. static boolean test1(){
  9. System.out.println("test1");
  10. return true;
  11. }
  12. static boolean test2(){
  13. System.out.println("test2");
  14. return false;
  15. }
  16. static boolean test3(){
  17. System.out.println("test3");
  18. return true;
  19. }
  20. static boolean test4(){
  21. System.out.println("test4");
  22. return false;
  23. }
  24. }
  25. /*
  26. test1
  27. test2
  28. test3
  29. test4
  30. test1
  31. test3
  32. */

boolean flag2 = test1()&&test3()||test2()&&test4();

若test1为true,test3为true时,因为前面这部分已经确定为true,所以后面部分不会被调用。

四、e

p49

科学与工程领域中,"e"代表自然对数的基数,为2.718。

而在C,C++和java(或者更多的语言)中,"e"代表“10的幂次”

$1.39e-43f = 1.39*10^{-43}$

五、位操作

p49

与,或,异或,非 &,|,^,~

与:所有的位都为1则输出1,否则输出0;

或:只要有一个位是1就输出1;

异或:两个位值相等时输出1;

非:1输出0,0输出1.

位运算不会出现短路现象。

p50

移位操作符:

$<<$:操作数向左移动,低位补0;

$>>$:操作数向右移动,(1)符号为正时,高位补0,(2)符号为负时,高位补1;

$>>>$:java独有操作符,操作数向右移动,高位统一补0。

char,byte,short进行移位操作时先会转成int类型,即32位

  1. public class URShift {
  2. public static void main(String[] args) {
  3. int i = 1024;
  4. System.out.println(Integer.toBinaryString(i));
  5. i >>= 10;
  6. System.out.println(Integer.toBinaryString(i));
  7. i = -1;
  8. System.out.println(Integer.toBinaryString(i));
  9. i >>>= 10;
  10. System.out.println(Integer.toBinaryString(i));
  11. i <<= 1;
  12. System.out.println(Integer.toBinaryString(i));
  13. short s = -1;
  14. s >>>= 10;//s移位后得到的结果在赋值时会强行转为int,所以移位后的s已经是int型
  15. System.out.println(Integer.toBinaryString(s));
  16. s = -1;
  17. System.out.println(Integer.toBinaryString(s>>>10));
  18. }
  19. }
  20. /*
  21. 10000000000
  22. 1
  23. 11111111111111111111111111111111
  24. 1111111111111111111111
  25. 11111111111111111111110
  26. 11111111111111111111111111111111
  27. 1111111111111111111111
  28. */

六、截尾

p55

将float或double转型为整数值时,总是对数字进行截尾,不会进行四舍五入。如果想要得到舍入的结果可以使用Math.round()

  1. public class CastingNumbers {
  2. public static void main(String[] args) {
  3. double d = 1.7d;
  4. int i = (int)d;
  5. System.out.println(i);
  6. i = (int) Math.round(d);
  7. System.out.println(i);
  8. }
  9. }
  10. //1
  11. //2

第四章(控制执行流程)

一、goto 标签

goto关键词,在java中则是使用标签代替臭名昭著的goto。其实在java中也是最好不要用标签来跳转语句,太伤智商。。

写法

outer:

并放在迭代语句前。

(1)continue 标签

跳出所有循环,并到标签位置的语句,但会重新进入紧接后面的循环里。

(2)break 标签

跳出所有循环,且不再进入紧接后面的循环里。

  1. public class LabeledFor {
  2. public static void main(String[] args) {
  3. System.out.println("测试continue————————————");
  4. label:
  5. for(int i=0;i<3;i++){
  6. System.out.println("外部for循环"+i);
  7. for(int j=0;j<3;j++){
  8. if(j==1){
  9. continue label;
  10. }
  11. System.out.println("内部循环"+j);
  12. }
  13. }
  14. System.out.println("测试break————————————————");
  15. label2:
  16. for(int m=0;m<3;m++){
  17. System.out.println("外部for循环"+m);
  18. for(int n=0;n<3;n++){
  19. if(n==1){
  20. break label2;
  21. }
  22. System.out.println("内部循环"+n);
  23. }
  24. }
  25. }
  26. }
  27. /*
  28. 测试continue————————————
  29. 外部for循环0
  30. 内部循环0
  31. 外部for循环1
  32. 内部循环0
  33. 外部for循环2
  34. 内部循环0
  35. 测试break————————————————
  36. 外部for循环0
  37. 内部循环0*/

第五章(初始化与清理)

一、重载

p81

重载主要以传入参数及顺序来区别。不能通过返回值来区别

以基本数据类型传入时:自动包装机制

(1)若传入的数据类型小于方法中声明的形式参数类型,实际数据类型就会提升。

byte->short->int->long->float->double

(2)如果传入的实际参数较大,就得通过类型转换执行窄化转换。

二、垃圾回收机制

p91

标记-清扫(Android中使用这个技术)

从堆栈和存储区出发,遍历所有的引用,进而找出所有存活的对象,并给与标记。遍历完成后,清理所有未被标记的对象。

停止-复制

先暂停程序的运行,然后将所有存活的对象复制到另一个堆,而没有复制的是可回收的内存。

三、初始化顺序

p94

所有的变量都会在任何方法(包括构造器)被调用之前得到初始化。

p95

无论创建多少对象,静态数据都只占用一份存储区域,static不能作用于局部变量。且静态初始化动作只执行一次。

四、可变参数列表。

p102

void method(Object... args){}

调用 method();或method(new Object[]{1,2,3,4});

第七章(复用类)

一、toString()的自动调用

p126

有时候编译器会自动帮你调用toString()方法。

"source"+ source;这时候会自动调用source对象的toString方法。

二、构造函数调用顺序

p130

构造函数总是从基类开始。

  1. class Insert{
  2. Insert(){
  3. System.out.println("Insert");
  4. }
  5. }
  6. public class Beetle extends Insert{
  7. Beetle(){
  8. System.out.println("Beetle");
  9. }
  10. public static void main(String[] args) {
  11. // TODO Auto-generated method stub
  12. Beetle b = new Beetle();
  13. }
  14. }
  15. //Insert
  16. //Beetle

三、final

p140

对于基本类型,final使数值恒定不变;而用于对象引用,final使引用恒定不变,但对象本身是可以改变的。

private 属于 final 方法

static final是属于类属性,即能被类调用,不用实例化

final则需要实例化。

四、组合模式

组合模式可以看做是一颗树,每个枝干都可以长出新的枝干,它们的结构都是相同的。

将枝干抽象为一个类,里面包含链接下一个节点的方法,若需要不断的链接下一个节点只需要继承这个方法并实现。

示例:导航菜单

组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性。

  1. public abstract class Tab {
  2. private String title;
  3. public Tab(String title) {
  4. this.title = title;
  5. }
  6. protected abstract void add(Tab tab);
  7. protected abstract void romove(Tab tab);
  8. }
  9. public class CardTab extends Tab{
  10. public CardTab(String title) {
  11. super(title);
  12. // TODO Auto-generated constructor stub
  13. }
  14. private List<Tab> tabs;
  15. @Override
  16. protected void add(Tab tab) {
  17. // TODO Auto-generated method stub
  18. tabs.add(tab);
  19. }
  20. @Override
  21. protected void romove(Tab tab) {
  22. // TODO Auto-generated method stub
  23. tabs.remove(tab);
  24. }
  25. }
  26. public class TabView {
  27. public static void main(String[] args) {
  28. // TODO Auto-generated method stub
  29. CardTab rootTab = new CardTab("roottab");
  30. CardTab tab1 = new CardTab("tab1");
  31. CardTab tab2 = new CardTab("tab2");
  32. CardTab tab3 = new CardTab("tab3");
  33. rootTab.add(tab1);
  34. rootTab.add(tab2);
  35. rootTab.add(tab3);
  36. CardTab tab4 = new CardTab("tab1-1");
  37. CardTab tab5 = new CardTab("tab1-2");
  38. tab1.add(tab4);
  39. tab1.add(tab5);
  40. }
  41. }
  42. /**
  43. * 这样子Tab组成了一个导航列表,这就是一个简单的组合模式.
  44. */

第八章(多态)

多态是一项让程序员“将改变的事物与未变的事物分离开来”的重要技术。

一、多态缺陷

p156

缺陷1:只有非private方法才可以被覆盖

  1. class Super{
  2. public int field = 0;
  3. public int getField(){return field;};
  4. }
  5. class Sub extends Super {
  6. public int field = 1;
  7. public int getField() { return field; }
  8. public int getSuperField() { return super.field; }
  9. }
  10. public class FiledAccess {
  11. public static void main(String[] args) {
  12. Super sup = new Sub(); // Upcast
  13. System.out.println("sup.field = " + sup.field +
  14. ", sup.getField() = " + sup.getField());
  15. Sub sub = new Sub();
  16. System.out.println("sub.field = " +
  17. sub.field + ", sub.getField() = " +
  18. sub.getField() +
  19. ", sub.getSuperField() = " +
  20. sub.getSuperField());
  21. }
  22. }
  23. 输出:
  24. sup.field = 0, sup.getField() = 1
  25. sub.field = 1, sub.getField() = 1, sub.getSuperField() = 0

缺陷2:域和静态方法直接在编译时候进行解析,所以多态不会对其产生作用。

  1. class StaticSuper {
  2. public static String staticGet() {
  3. return "Base staticGet()";
  4. }
  5. public String dynamicGet() {
  6. return "Base dynamicGet()";
  7. }
  8. }
  9. class StaticSub extends StaticSuper {
  10. public static String staticGet() {
  11. return "Derived staticGet()";
  12. }
  13. public String dynamicGet() {
  14. return "Derived dynamicGet()";
  15. }
  16. }
  17. public class StaticPolymorphism {
  18. public static void main(String[] args) {
  19. StaticSuper sup = new StaticSub(); // Upcast
  20. System.out.println(sup.staticGet());
  21. System.out.println(sup.dynamicGet());
  22. }
  23. } /* Output:
  24. Base staticGet()
  25. Derived dynamicGet() */

二、断言

p153

@Override作用:

断言,如果我们使用了这种annotation在一个没有覆盖父类方法的方法时,java编译器将以一个编译错误来警示

三、构造器构造顺序

p158

构造器在多态时的构造顺序:

  1. class Meal {
  2. Meal() {
  3. P.print("Meal()");
  4. }
  5. }
  6. class Bread {
  7. Bread() {
  8. P.print("Bread()");
  9. }
  10. }
  11. class Cheese {
  12. Cheese() {
  13. P.print("Cheese()");
  14. }
  15. }
  16. class Lettuce {
  17. Lettuce() {
  18. P.print("Lettuce()");
  19. }
  20. }
  21. class Lunch extends Meal {
  22. Lunch() {
  23. P.print("Lunch()");
  24. }
  25. }
  26. class PortableLunch extends Lunch {
  27. PortableLunch() {
  28. P.print("PortableLunch()");
  29. }
  30. }
  31. public class Sandwich extends PortableLunch {
  32. private Bread b = new Bread();
  33. private Cheese c = new Cheese();
  34. private Lettuce l = new Lettuce();
  35. public Sandwich() {
  36. P.print("Sandwich()");
  37. }
  38. public static void main(String[] args) {
  39. new Sandwich();
  40. }
  41. }
  42. class P {
  43. public static void print(String s){
  44. System.out.println(s);
  45. }
  46. }
  47. 输出:
  48. Meal()
  49. Lunch()
  50. PortableLunch()
  51. Bread()
  52. Cheese()
  53. Lettuce()
  54. Sandwich()

解释说明:

一个继承类实例化的时候必须要确保所使用的成员已经构建完毕,所以必须先调用基类的构造器,所以当实例化Sandwich对象时先调用其基类的构造方法:

Meal()

Lunch()

PortableLunch()

其次对成员变量进行初始化

Bread()

Cheese()

Lettuce()

最后调用构造器

Sandwich()

三、构造器初始化

p163

初始化的过程:

(1)在所有事物发生之前,将分配给对象的存储空间初始化为二进制的零。

(2)调用基类构造器。

(3)按照声明顺序调用成员的初始化方法。

(4)调用导出类(本体)的构造器主体。

《Java编程思想》阅读笔记一的更多相关文章

  1. <<浪潮之巅>>阅读笔记一

    第一次的阅读就想读这本书的,却因为很多愿意一直拖到现在,因为听说这本书在李开复先生 的微博上有推荐,更是增加了我的阅读兴趣.可能是因为在网上找的电子版的原因,通篇阅读的速度很快,但是没有纸质数那种细嚼 ...

  2. <<浪潮之巅>>阅读笔记三

    纵看世界,横看国内.我们国内也有很多很优秀的企业正在走向或者已经处于浪潮之巅.阿里巴巴.腾讯和百度这三巨头应该是我们计算机行业的龙头.但是 不得不说,在创新方面我们做的并不多,这是值得每一个从事计算机 ...

  3. <<浪潮之巅>>阅读笔记二

    好的文章总是慢慢吸引着你去阅读,这本书的作者是吴军博士,让我很钦佩的是他还是一个很著名的程序员.其实我感觉理科生在写作方面的能力是很欠缺的,我们经常做到了有观点,但是做不到和别人表达清楚你的观点想法, ...

  4. <浪潮之巅>读书笔记

    <浪潮之巅>这本书通过介绍AT&T.IBM.微软.苹果.google等IT公司的发展历史,揭示科技工业的胜败规律,说明这些公司是如何在每一次科技革命浪潮到来时站在浪尖,实现跨越式发 ...

  5. 【kindle笔记】之 《浪潮之巅》- 2018-1-

    <浪潮之巅> 这本书推荐自最爱的政治课老师. 政治课老师张巍老师.我会一直记得你的. 以这样的身份来到这个学校,他人的质疑,自己的忐忑,老板的不公.犹犹豫豫谨小慎微地前进. 第一次听到这样 ...

  6. 阅读笔记 1 火球 UML大战需求分析

    伴随着七天国庆的结束,紧张的学习生活也开始了,首先声明,阅读笔记随着我不断地阅读进度会慢慢更新,而不是一次性的写完,所以会重复的编辑.对于我选的这本   <火球 UML大战需求分析>,首先 ...

  7. [阅读笔记]Software optimization resources

    http://www.agner.org/optimize/#manuals 阅读笔记Optimizing software in C++   7. The efficiency of differe ...

  8. 《uml大战需求分析》阅读笔记05

    <uml大战需求分析>阅读笔记05 这次我主要阅读了这本书的第九十章,通过看这章的知识了解了不少的知识开发某系统的重要前提是:这个系统有谁在用?这些人通过这个系统能做什么事? 一般搞清楚这 ...

  9. <<UML大战需求分析>>阅读笔记(2)

    <<UML大战需求分析>>阅读笔记(2)> 此次读了uml大战需求分析的第三四章,我发现这本书讲的特别的好,由于这学期正在学习设计模式这本书,这本书就讲究对uml图的利用 ...

  10. uml大战需求分析阅读笔记01

    <<UML大战需求分析>>阅读笔记(1) 刚读了uml大战需求分析的第一二章,读了这些内容之后,令我深有感触.以前学习uml这门课的时候,并没有好好学,那时我认为这门课并没有什 ...

随机推荐

  1. [洛谷P2495][SDOI2011]消耗战

    题目大意:有一棵$n(n\leqslant2.5\times10^5)$个节点的带边权的树,$m$个询问,每次询问给出$k(\sum\limits_{i=1}^mk_i\leqslant5\times ...

  2. 一些技巧 && 常数优化 && 出现の错误

    开坑原因 7.21 今天DTZ大爷教了我一个算欧拉函数的好方法......是质因数复杂度的 这让我想到,这些小技巧小idea,很多时候,可能就是考场上最致命.最一击必杀的"大招" ...

  3. BZOJ2875 & 洛谷2044:[NOI2012]随机数生成器——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=2875 https://www.luogu.org/problemnew/show/P2044 栋栋 ...

  4. [bzoj] 1040 骑士 || 基环外向树dp

    原题 给出n个点n条边和每个点的点权,一条边的两个断点不能同时选择,问最大可以选多少. //图是一张基环外向树森林 是不是很像舞会啊- 就是多了一条边. 所以我们考虑一下对于一棵基环外向树,拆掉一条在 ...

  5. SAPI 包含sphelper.h编译错误解决方案

    原文连接地址:http://blog.csdn.net/believenow_notfuture/article/details/52191229 [转]SAPI 包含sphelper.h编译错误解决 ...

  6. JavaScript中进制之间的转换

    JavaScript中进制之间的转换 //十进制转其他 var x = 100; alert(x); alert(x.toString(2)); //转2进制 alert(x.toString(8)) ...

  7. Good Bye 2015 C

    C. New Year and Domino time limit per test 3 seconds memory limit per test 256 megabytes input stand ...

  8. 如何让浏览器在访问链接时不要带上referer

    function open_without_referrer(link){ document.body.appendChild(document.createElement('iframe')).sr ...

  9. [mysql]tpcc相关及画图

    参考:http://blog.chinaunix.net/uid-26896862-id-3563600.html 参考:http://blog.chinaunix.net/uid-25266990- ...

  10. HDU1828线段树(扫描线)

    Picture Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...