Thinking in Java 中闪耀的星星(一)
**”Thinking in java” 被誉为Java界的圣经,做为进阶是一个不错的选择,暑假在家闲着无聊,看着打发打发时间,把一些自己认为不错的点做了一些笔记。文字部分是我的见解,代码大部分取自原书。顺便我想给三个看Tij的建议:
1).看英文原著!中文版的翻译并不是原汁原味的翻译,而是意译,为了中文句式的流畅,有些意思会被篡改。
2).不要抱着想一次读完的心态!一本好书,是经得起时间的考验,必定要反复啃,温故而知新。
3).学习就像吃饭,书是香喷喷的米饭,视频是脍炙人口的菜,优酷上有一套斯坦福大学的《编程方法》公开课,刚好是选择以java为讲解语言的,可以跟看书同步:http://list.youku.com/albumlist/show/id_17643804.html?sf=10100&spm=0.0.0.0.bL8hk1**
下面我们开启Thinking之旅:
1.什么是面向对象编程?
1.)我们所处的世界是由对象构成的,java的设计的本质也是基于世界的!在理解什么是面向对象要先清楚“自顶而下”的设计思想,就是把大的方面细分为小的方面,直到原子性,比如,早上洗漱,细分为洗脸,刷牙,刷牙细分为挤牙膏,牙刷刷动牙齿…
2.)为什么是面向对象?举个例子:人类的上层是灵长类,灵长类的上层是哺乳动物,哺乳动物的上层是动物,那么人类、灵长类、哺乳动物、动物就称为类,我/你/他是人类的一个实例,称为对象,那么推广出去,java是面向对象的语言,不就反映出世界的物质性吗。
3.)对象的作用是接收发送过来的指令,做出回应。每个对象之间相互提供服务。对象向对象发送信息。好比生活中的例子:我把CD插入CD播放器,播放音乐。我、CD、CD播放器、音乐均是对象。
2面向对象特性?
抽象、继承、多态、封装。
本质是实现代码高内聚,低耦合,增强代码复用性。
3.String s = new String(“string s”);包含了什么?
里面的s代表一个引用,存在栈中,引用的名字 s 存在变量区,new 把 s 引用与String关联,String是一个类,存在堆。
4.Array 细节
1.)Array在创建时它的每个元素默认为null。
2.)如果:
List list=null;
list=…
会报空指针异常。
5.Java命名规则
类名的每个单词首字母大写
变量名和方法名的第一个单词的首字母小写,其余的首字母大写
6.注释
具体看下面的hello world 例子:
//:object/HelloDate.java
import java.util.*;
/**The first Thinking in Java example program.*Displays a String and today's date*@author wayne*@version 4.0*/
public class HelloDate{/**Entry point to class & application.*@param args array of string arguments *@throws exceptions No exception thrown*/public static void main(String[] args){System.out.println("Hello World,it's:");System.out.println(new Date());}
}/*Output:(55% match)
Hello World. it's:
Web July 14 17:42:36 MCT 2016
*///~
7.equals()方法陷阱
看例子:
public class EqualsMethod{public static void main(String[] args){Integer n1=new Integer(47);Integer n2=new Integer(47);System.out.println(n1.equals(n2));System.out.println("***********");Value v1=new Value();Value v2=new Value();v1.i=v2.i=100;System.out.println(v1.equals(v2));}
}
class Value{int i;
}/*Output
true
**********
false
*/
很奇怪为什么一个是true,一个是false?
equals()是object的方法,用来比较对象的地址。所有类都是object的子类,Integer同样也是object的子类,也包含有equals()方法,但是Integer重写了equals()方法,用来比较两个Integer对象的数值。上面的例子中,Integer.equals()比较两个47的值相等而返回true,而Value类并没有重写equals()方法,比较的是new出来的对象的地址,两个对象的地址不同而返回false。
8.Java没有sizeof()函数
C语言中,经常用sizeof()在来定义数据类型的长度。操作系统是16/32/64…位的时候,不同数据类型的大小不一样。但是Java语言在设计时,不要sizeof(),所以在每个机器上各种数据类型的大小是固定的,使得java可以在各个平台来去自如,这就是Java的可移植性,所谓的跨平台。
9.Java的变量可以边用边定义
for(int i=0;i<10;i++)
而C不可以,i的作用域(生命周期)只在当前for循环中。
10goto做为Java的保留字,但是并不使用
在Java中,如果有嵌套的循环语句,当需要从某个循环跳出到指定的循环时,可以用label,定义一个label,然后再加在break或continue后面,看例子:
public class LabeledFor{public static void main(String[] args){int i=0;outer:for(;true;){inner:for(;i<10;i++){System.out.println("i="+i);if(i==2){System.out.println("continue");continue;}if(i==3){System.out.println("break");i++;break;}if(i==7){System.out.println("continue outer");i++;continue outer;}if(i==8){System.out.println("break outer");break outer;}for(int k=0;k<5;k++){if(k==3){System.out.println("continue inner");continue inner;}}}}}
}/*Output
i=0
continue inner
i=1
continue inner
i=2
continue
i=3
break
i=4
continue inner
i=5
continue inner
i=6
continue inner
i=7
continue outer
i=8
break outer
*///~
11.overloading(重载)为什么要使用传入的参数区分?
在开发中我们定义对象名称和方法时, 一般采取语义法,但是为了拓展方法,会多出几个方法,又不想改动通俗易懂的方法名,于是采用不同参数区分开来。那位什么不通过返回值呢?因为当你只声明而不接收方法的返回值时,java编译器无法区分哪个方法被调用。
12.初始化一个对象的顺序
先初始化变量,再初始化方法。
13.方法的权限控制
public、package-access、private、protected
public:Everything naked to the world.所有对象都可以访问
package-access:顾名思义,同一个包内的可以访问(包:存放一堆类的namespace)
private:除了对象本身,其他对象均不能访问。主要用于解耦。
protected:住要用于修饰父类的方法。被修饰的方法可以被继承该对象的子类访问,其他对象不能访问
14.类的权限
类的权限之有两个:public、package-access。用法与方法一致。当public修饰一个类时,代表该类的所有内容都是public。另外,在一个java文件中,必须要有一个public的类。
15.is-a(继承/inheritance) vs has-a(合成/composition)
合成就是在一个类中整合进其他类构成一个新的类。它的灵活性,适应性比继承更好,但是每个类之间的变量和方法必须是public,封装性不如继承。
Bruce建议只有在确定能用继承是才用继承。实际编程中是继承和合成混用的。
16.final关键字修饰方法的作用
1.防止方法被重写
2.优化程序:一般的程序是通过压栈和出栈实现的,被final修饰的方法不会进栈,当程序运行到调用被final修饰方法的语句时,编译器直接把被final修饰的方法的代码拼接到语句后面,直接编译,提高速度。
17.构造器的调用顺序
1.从继承的根部开始调用构造方法
2.根据声明的顺序初始化变量
3.子类构造器的内部开始执行
看例子:
class Meal{Meal(){System.out.println("Meal()");}
}
class Bread{Bread(){System.out.println("Bread()");}
}
class Cheese{Cheese(){System.out.println("Cheese()");}
}
class Lettuce{Lettuce(){System.out.println("Lettuce()");}
}
class Lunch extends Meal{Lunch(){System.out.println("Lunch()");}
}
class PortableLunch extends Lunch{PortableLunch(){System.out.println("PortableLunch()");}
}
public class Sandwich extends PortableLunch{private Bread b=new Bread();private Cheese c=new Cheese();private Lettuce l=new Lettuce();public Sandwich(){System.out.println("Sandwich()");}public static void main(String[] args){new Sandwich();}
}/*Output
Meal()
Lunch()
PortableLunch()
Bread()
Cheese()
Lettuce()
Sandwich()
*///~
18.继承和清除对象的顺序
从17的例子可以看出在继承关系中,方法的调用是从根部,最先的父类开始逐级调用。如果,想在对象被使用后回收该对象,释放内存空间。那么,调用回收函数的顺序是与继承相反的,为的是防止父类的方法被子类调用而回收父类的情况。
19.private 和 final
private默认是final。在使用多态时,如果想在构造器中调用方法,尽量把方法写在父类的构造器里。而且方法最好不要被重写,以免造成一些不必要的难以察觉的惊喜。
20.接口与抽象类的作用
在一般的继承关系中,父类的方法往往不会用到,而是使用子类重写的方法。父类的方法只是声明,所以接口和抽象类出现了。但是接口比抽象类更抽象。
抽象类不可被实例化,一般用来给子类继承;
接口最主要还是用来解耦合,接口允许被多个类实例化,增强代码的复用性,主要体现在适配器模式中。接口声明的方法默认为public,变量默认为static final
21.接口的“工厂”用法
直接看例子:
interface Game{boolean move();
}
interface GameFactory{Game getGame();
}
class Checkers implements Game{private int moves = 0;private static final int MOVES = 3;public boolean move(){System.out.println("Checkers move "+moves);return ++moves != MOVES;}
}
class CheckersFactory implements GameFactory{public Game getGame(){return new Checkers();}
}
class Chess implements Game{private int moves = 0;private static final int MOVES = 4;public boolean move(){System.out.println("Chess move "+moves);return ++moves!=MOVES;}
}
class ChessFactory implements GameFactory{public Game getGame(){return new Chess();}
}
public class Games{public static void playGame(GameFactory factory){Game s= factory.getGame();while(s.move()){;}}public static void main(String[] args){playGame(new CheckersFactory());playGame(new ChessFactory());}
}/*Output
Checkers move 0
Checkers move 1
Checkers move 2
Chess move 0
Chess move 1
Chess move 2
Chess move 3
*///~
22.内部类的作用
内部类的设计初衷是解决接口的实现类的拓展缺陷。
内部类与外围类一起使用,外围类不管继承/实现什么接口,内部类也可以实现什么接口,独立于外围类。但是访问时要先访问外围类(除非内部类被static final修饰)。具体在程序中的作用可以参考 “Thinking in java” 原著第四版,P376~P380的例子。
内部类也称为闭包。
23.Local Inner Class vs anonymous Inner Class(匿名内部类)
先看一个例子:
interface Counter{int next();
}
public class LocalInnerClass{private int count =0;Counter getCounter(final String name){class LocalCounter implements Counter{public LocalCounter(){System.out.println("LocalCounter()");}public int next(){System.out.println(name);return count++;}}return new LocalCounter();}Counter getCounter2(final String name){return new Counter(){{System.out.println("Counter()");}public int next(){System.out.println(name);return count++;}};}
public static void main(String[] args){LocalInnerClass lic=new LocalInnerClass();Counterc1=lic.getCounter("Local inner"),c2=lic.getCounter2("Anonymous inner");for(int i=0;i<5;i++){System.out.println(c1.next());}for(int i=0;i<5;i++){System.out.println(c2.next());}}
}/*Output
LocalCounter()
Counter()
Local inner
0
Local inner
1
Local inner
2
Local inner
3
Local inner
4
Anonymous inner
5
Anonymous inner
6
Anonymous inner
7
Anonymous inner
8
…
1.如果需要自己定义内部类的构造器或重写内部类的构造器,还是用local inner class
2.如果想为一个内部类创建多个对象,也还是使用 local inner class
24.集合的关系
collection 和 map 是最上层的类,其中:List,Set,Queue继承collection。List又衍生出ArrayList 和 LinkedList,Set衍生出HashSet 和 TreeSet,HashSet又衍生出LinkedHashSet,Queue 衍生出 PriorityQueue。HashMap ,TreeMap 继承Map ,HashMap又衍生出LinkedHashMap。
1.Map的功能强于Collection
2.List中元素是有顺序的
3.ArrayList适用于大规模查找,LinkedList适用于大规模插入和删除元素
4.TreeMap的key值是经过排序的,所以速度不如HashMap快
5.Set的元素不能重复,LinkedHashSet的元素的顺序是跟插入顺序一样的
25.stack 和 queue
这两个集合用的比较少几乎没用了,但是原理跟数据结构是一样的。stack是先入后出,queue是先入先出:
Stack:
import java.util.*;
public class StackTest{public static void main(String[] args){Stack<String> stack=new Stack<String>();for(String s:"My dog has fleas".split(" ")){stack.push(s);}while(!stack.empty()){System.out.print(stack.pop()+" ");}}
}/*Output
fleas has dog My
*///~
Queue:
import java.util.*;
public class QueueDemo{public static void printQ(Queue queue){while(queue.peek()!=null){System.out.print(queue.remove()+" ");}System.out.println();}public static void main(String[] args){Queue<Integer> queue=new LinkedList<Integer>();Random rand=new Random(47);for(int i=0;i<10;i++){queue.offer(rand.nextInt(i+10));}printQ(queue);Queue<Character> qc=new LinkedList<Character>();for(char c: "Brontosaurus".toCharArray()){qc.offer(c);}printQ(qc);}
}/*Output
8 1 1 1 5 14 3 1 0 1
B r o n t o s a u r u s
*///~
Thinking in Java 中闪耀的星星(一)相关推荐
- Thinking in Java 中闪耀的星星(四)
51.对象序列化的具体应用 这也是书里的一个例子,挺有意思的.结合模板方法模式模拟CAD将用户作业的信息保存在文件中: import java.io.*; import java.util.*; ab ...
- Thinking in Java 中闪耀的星星(三)
41.容器集合的选择 List容器无非分为两大种,基于数组和基于链表:数组有索引,所以查找快,链表插入删除不需要移动全部元素,插入删除快. ArrayList/Vector查找快,LinkedList ...
- java中frame窗体星星坠落_java窗体绘漫天星星和月亮
源代码如下: package zuoye3; import java.awt.*; import java.util.Random; public class frameshy { public st ...
- java中循环语句_Java语法基础之循环结构语句详解
一.循环结构 循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复执行这个循环体时,需要在合适的时候把循环判断条件修改为false,从而结束循环,否则循 ...
- java中函数的调用,java中如何调用函数
java动态调用函数,Java 中使用动态代码,java函数调用,java中如何调用函数 如何在 Java 中调用 C 函数 宗薇 [期刊名称]<网络新媒体技术> [年(卷),期]2000 ...
- luoguP3353 在你窗外闪耀的星星
P3353 在你窗外闪耀的星星 题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向 ...
- 洛谷 P3353 在你窗外闪耀的星星
洛谷 P3353 在你窗外闪耀的星星 题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室, ...
- 【洛谷 3353】在你窗外闪耀的星星
题目描述 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀着你玫瑰色的 ...
- 【洛谷】【线段树】P3353 在你窗外闪耀的星星
[题目描述:] /* 飞逝的的时光不会模糊我对你的记忆.难以相信从我第一次见到你以来已经过去了3年.我仍然还生动地记得,3年前,在美丽的集美中学,从我看到你微笑着走出教室,你将头向后仰,柔和的晚霞照耀 ...
最新文章
- NeurIPS 2019公布获奖论文!新增杰出新方向奖项,微软华裔研究员斩获经典论文...
- leetcode2 两数相加
- 20165310java_blog_week6
- 获取界面url_PHP调用百度地图接口,根据IP地址获取地区
- 【数据结构与算法】之深入解析“课程表II”的求解思路与算法示例
- [C++11]独占的智能指针unique_ptr的删除器
- qt与js html进行数据传递,QT与javascript交互数据的实现
- 求出千位数上的数加百位数上的数等于十位数上的数加个位数上的数的个数cnt,再把所有满足条件的四位数依次存入数组b中,然后对数组b中的四位数按从大到小的顺序进行排序。
- k8s中yaml文件pod的语法(转)
- C++11在加入<thread>头文件后Socket服务器接收不到消息
- 【PowerShell】逐行处理文本示例
- PRML 1.5 决策论
- 离散数学之主析取范式,主合取范式
- CATIA怎么约束快捷键_CATIA超实用快捷键和技巧
- FatFs 之三 FAT文件系统基础、FAT 数据格式、引导、编码
- Android 更换皮肤思路及解决方案
- Fe3O4纳米颗粒的表面接枝修饰/氨基乙酸|L-半胱氨酸(L-Cys)修饰的Fe3O4包裹TiO2(Fe3O4@TiO2/L-Cys)复合纳米粒子
- 清爽的VS开发字体 -- Consolas
- 至快乐的11.11---牛X光棍的呐喊!(转)
- Gtk-ERROR : GTK+ 2.x symbols detected. Using GTK+2.x and GTK+3 in the same process is not support
热门文章
- JavaScript中JSON字符串转JSON对象遇到的问题
- 11个提高开关电源效率的小技巧
- java 单链表 添加 插入 删除
- 易语言复制代码到记事本时出现乱码
- R语言 计算 最小二乘法 代码 流程
- 汽车ECU软件开发之应用层软件与底层软件
- .NET Core 3.0 正式公布:新特性详细解读
- nitro库_Nitro的故事,专业的翻译服务,可帮助开发人员进行本地化和多语言支持...
- 暑期2020“大咖说开源”之 孙金城:参与 ASF 开源贡献的正确姿势
- 【Android-Service】基于MVP的音乐播放器demo实现思路(附源码)