参考文献(References)
[1] Bruce Eckel.Java编程思想(ThinkingJava FourEdition)第四版[M].陈昊鹏,北京:机械出版社,2007.6(2014.11重印)
看完一本书很容易,但是想要把一本书实践完并精通的话,没有长时间研读是别想的。
1.1: Unified Modelling Language统一建模语言,类名在顶部,数据成员在中间部分,方法在底部
1.2: 复用某个类,直接使用该类的一个对象
1.3: 使用现有的类合成一个新类称为组合、动态发生称为聚合
1.4: 组合→拥有 汽车◆▬引擎
1.5: 处处使用继承导致难以使用并过分复杂的设计
1.6: 建立新类时,优先考虑组合
1.7: 有了经验后能够看出必须使用继承的场合了
1.8: 创建了一个新类后,有另一个新类与之相似,此时可用继承
1.9: 基类◁▬导出类
1.10: 使用继承构建一个类型层次结构
1.11: 使基类与导出类产生差异:
1.12: ① 直接在导出类中添加新方法
1.13: ② 覆盖@Override使用相同的接口方法,做些不同的事情
1.14: 导出类只覆盖基本的方法叫纯粹代替,替代原则,is-a关系
1.15: 后期绑定,向对象发送信息,被调用的代码知道运行时才能确定
1.16: 编译器确保被调用方法的存在,并不知道将被执行的确切代码
1.17: C++用Virtual实现后期绑定
1.18: Java是默认的
1.19: 向上转型
1.20: 把导出类看成是基类
1.21: Java中所有的类都基于一个类Object
1.22: 单根继承结构:① 共用一个接口 ② 保证所有的对象都具备某些功能
1.23: 使垃圾回收栈的实现变得容易得多
1.24: Java中容器和集合有不同的含义
1.25: 标准模板类库(standart template library,STL)
1.26: 可视化构件库(Visual Component Library,VCL)
1.27: List存储序列,Map关联数组
1.28: Set(每种对象类型只持有一个)
1.29: 参数化类型——泛型
1.30: 堆的内存池中创建对象
1.31: Java垃圾回收机制自动发现对象何时不再被使用,继而销毁它
1.32: 机器底层的知识来编写中断服务机制,主进程的挂起通过硬件中断来触发
1.33: 并发最常见的例子就是用户界面
1.34: 共享资源:某个任务锁定某项资源
1.35: 完成其任务,然后释放资源锁,使其他任务可以使用这项资源
1.36: 客户/服务器系统具有一个中央信息存储池(central repository of information),存储某项数据(通常 in DB)
1.37: 分发给某些人员或机器集群
1.38: 客户端编程: 1. 插件plug-in 2.脚本语言Java是基于C++的
1.39: String创建的只是引用并不是对象
1.40: 带引号的文本初始化,必须采用更通用的初始化方法 new String("asdf")
1.41: 寄存器(最快),堆栈(随机访问存储器RAW),堆(通用的内存池,位于RAM区),常量存储(ROM只读存储器),非RAM存储(数据完成活于程序之外),流对象和持久性对象
1.42: 流对象,字节流,发送往另一台机器
1.43: 持久化对象存放于磁盘中,把对象转化成可以存放在其他媒介上的事物
1.44: 基本类型char <-> 包装器类型character
1.45: 高精度BigInteger和BigDecimal
1.46: 每个引用自动初始化为null
1.47: Java不允许用{}隐藏变量如:{int x;{int x;}}
1.48: 出作用域,引用s消失,指向的String对象仍占据内存
1.49: 垃圾回收器辨别不再引用的对象使其释放
1.50: char的默认值'\u0000'(null)
1.51: 变量作为类的成员使确保给定其默认值0,不适用于局部变量,得到的是任意值,Java会Error
1.52: Java的函数叫方法
1.53: Java设计者希望程序使用自己的Internet域名,保证它们肯定是独一无二的
1.54: java.lang默认导入到每一个Java文件中
1.55: System.out(PrintStream)
1.56: java.library.path
1.57: @see link docRoot inheritDoc version author…… P34
1.58: 驼峰风格
1.59: 静态导入static import,import static XXX
1.60: 取右边的值(右值)复制给左边(左值)
1.61: t1 = t2 , 将t1绑定到t2上导致t1指向的对象丢失
1.62: Random.nextInt()
1.63: 无符号右移位操作符>>>,无论正负在高位插0
1.64: 在C和C++中,while(x=y){}y为非零值则无限循环
1.65: 类型转换cast
1.66: 窄化转换narrowing conversion,多信息type→少信息type,需要显示转换
1.67: 扩展转换widening conversion,少信息type→多信息type
1.68: 整数溢出不会警告出错或出现异常!
1.69: 唯一用到逗号操作符的地方是for,其它时候是逗号分隔符
1.70: foreach语法for(float x:f)
1.71: Java无goto
1.72: 带标签outer的continue到达标签为止,break+标签跳出标签所指的循环
1.73: Tree(int)是唯一的构造器则无其它构造方式
1.74: 参数类型顺序不同也能重载→代码难以维护
1.75: 要是在代码中出现了大量static方法,就该重新考虑自己的设计了
1.76: finalize()对象可能不被垃圾回收,垃圾回收不等于“析构”
1.77: 垃圾回收器不能完全代替析构函数,也绝对不能直接调用finalize()
1.78: protected void finalize(){if(boolean)Erro:checked out}被当做垃圾胡思后前将boolean置false(初始化为true),一旦忘记,用system.gc()销毁
1.79: super.finalize()
1.80: 垃圾回收器一面工作,一面使堆中的对象紧密排列,“堆指针”更容易移动传送带开始处
1.81: 对象←引用计数器,引用+1,出作用域或null、-1。0释放
1.82: 对象之间循环引用,该回收时引用计数不会零
1.83: 更快的模式,追溯到堆栈和静态存储区的引用,引用追踪对象→所有引用,解决交互自引用对象组的问题
1.84: 自适应,停止-复制stop-copy,将所有存活的对象从当前堆复制到另一堆,没有被复制到的全部都是垃圾,堆复制后对象一个接一个
1.85: 按需从堆中分配几块较大的内存,操作在这几块内存之间进行
1.86: 没有新垃圾——产生,换标记——清扫(mark and sweep),产生少量垃圾时快
1.87: 即时编译器,翻译成本地机器码
1.88: 转载类→找到.class文件→该类的字节码转入内存→即时编译器、惰性评估,只在必要的时候用即时编译器
1.89: 构造器初始化:类变量i先置0再变7,变量先于方法调用初始化
1.90: Table类名静态对象B在Table第一次创建或第一次访问静态数据时创建
1.91: 构造器实际上也有静态方法
1.92: Integer[] a= new Integer[20]
1.93: 引用数组,没有初始化就调用会产生异常
ENDP100 20151123 星期一
2.1: static void printArray(Object……args)
2.2: 可变参数列表枚举类型集
2.3: public enum Spiciness{}
2.4: 事实上enum是类
2.5: 重构及重写代码
2.6: 环境变量CLASSPATH中放路径,路径中饭.class文件,Java解释器会在这里面找
2.7: jar文件需要指明,定制工具库,包访问权限
2.8: 默认访问权限包内可见包外为private
2.9: accessor(get),mutator(set)方法
2.10: java文件内无public类是可能的,此时文件可随意命名
2.11: 唯一的public class是该文件的对外接口
2.12: 类不能是private也不能是protected
2.13: 定义对象的地方初始化先于构造器
2.14: 在使用这些对象之前初始化,减少额外的负担,叫惰性初始化
2.15: 代理
2.16: @Override注解,可以防止你在不想重载时而意外地进行了重载,即你本来想重写基类的一个方法,单参数和返回值不对导致与想重写的那个方法不同,这是重载
2.17: 组合能显示地分解一个类的功能使其清晰可见,继承则是全部函数堆在一起
2.18: 将域保持为private,保留更改底层实现的权利,通过protected方法控制类的继承类访问权限
2.19: 可以在域的定义处或构造器给final初始化
2.20: final+方法把方法锁定不让继承类覆盖
2.21: private隐式指定final
2.22: final+class不允许继承
2.23: 多态(动态绑定,后期绑定或运行时绑定)
2.24: 绑定,一个基类和二子类都play(),上转型基类来作参,调用play,调用哪个类的play()
2.25: 后期绑定,根据对象类型进行绑定
2.26: 子类方法采取与基类private方法不同的名字
2.27: 清理:给类创建dispose方法
2.28: 共享对象时不能简单地调用dispose()
2.29: 交给引用计数处理 P161
2.30: 纯粹继承,完全的is-a关系,导出类完全可以代替基类
2.31: ClassCastException类转型异常,运行时类型识别RTTI
2.32: public abstract void play(Noten)
2.33: 抽象类比较有用的重构工具
2.34: interface接口
2.35: 接口方法必须是public
2.36: 完全解耦,策略设计模式
2.37: 根据所传递参数对象不同而具有不同行为的方法
2.38: extends Processor和extends Filler的不同类、执行Apply,process(Processor)时,前者可以,后者不能,即便可以运行,因为Processor和Filter的成员基本一致(不同在Object和Waveform上,后者是前者子类)
2.39: 这就叫耦合,以此引出interface
2.40: 接口从具体实现中的解耦使得接口可以应用于多种不同的具体实现
2.41: 接口嵌套在类中
2.42: 内部类可以访问外部类所有元素
2.43: dn.newInner(),创建的内部类对象,必须使用外部类对象,静态除外
2.44: 方法内定义类——局部内部类
2.45: 匿名内部类用外部定义的对象需要用final
ENDP200 20151124 Tuesday
3.1: 优先使用类而不是接口
3.2: 如果你的设计中需要某个接口,你必须了解它,否则不到迫不得已,不要将其放入你的设计中
3.3: 不需要内部类对象与起外围类对象之间有联系,那么内部类声明为static,这通称为嵌套类
3.4: static应用于内部类时的含义
3.5: 普通的内部类隐式地保存了一个引用
3.6: 内部类是static的时候就不是这样的了
3.7: 普通的内部类不能有static数据和static字段
3.8: C++嵌套类只不过C++不能访问私有成员,Java可以
3.9: 每个类放main()方法测试这个类,却必须带着编译过的额外代码,所以可以用嵌套类来测试代码,最后可简单地删除Tester.class
3.10: 在内部类实现外围接口
3.11: 一个内部类被嵌套多少层并不重要——透明地访问所有它所嵌入的外围类的所有成员
3.12: 内部类允许接受多个非接口类型(类或抽象类),多重继承
3.13: 如果Sequence.java不使用内部类就必须声明"Sequence是一个Sector",对于某个特定的Sequence只能有一个Selector
3.14: 然而使用内部类很容易就能拥有另一个方法reverseSelector()、用它来生成一个反方向遍历序列的Selector
3.15: 只有内部类才有这种灵活性
3.16: 练习22
3.17: 闭包closure
3.18: 内部类有权操作所有的成员、包括private
3.19: 记录了一些来自其作用域的信息
3.20: 回调、携带在稍后时刻调用它初始的对象的信息
3.21: 实现GUI功能时,到处都用到了回调
3.22: extends和implements有相同名字的函数时使用内部类进行区分
3.23: 回调——别的类获取该类中内部类接口的引用,回调该类
3.24: 控制框架control framework,应用程序框架(application framework)
3.25: 运用af:继承一至多个类,覆盖某些方法,以解决特定问题
3.26: Java Swing库使用了大量的内部类
3.27: List<> -> add,size,foreach,remove
3.28: 继承内部类需要将外部类的引用传进来
3.29: 继承外部类要继承内部类,外/内部类都需要继承,直接定义内部类不继承是不能覆盖的
3.30: 类产生,class文件,meta-class外围类名+&+内部类名+.class
3.31: 一个程序包含固定数量且生命周期都是已知的对象
3.32: List必须按照插入的顺序来保存元素,Set不能有重复元素..Queue排队
3.33: Map键值对,ArrayList数字来查值
3.34: ArrayList -> List 上转型
3.35: Arrays.asList(1,2,3,4,5)
3.36: Collection
3.37: Map.put(key,value),Map.get(key)
3.38: HashMap,TreeMap,LinkedHashMap
3.39: HashSet,HashMap
3.40: contains()确定某个对象是否在列表汇总
3.41: 可以将这个对象的引用传递给remove()方法
3.42: subList()、retainAll()、removeAll()、toArray()
3.43: 迭代器
3.44: LinkedList可用作栈、队列或双端队列的方法
3.45: Set不保存重复的元素
3.46: HashSet
3.47: TreeSet——红黑色数据结构
3.48: Set类用了散列
3.49: 想对结果排序用TreeSet代替HashSet
3.50: SortedSet
3.51: new.mindview.TextFile,打开一个文件,将其读入一个Set
3.52: Set
3.53: String.CASE_INSENTIVE_ORDER按照字母序排列
3.54: 扩展到多维Map
3.55: Queue先进先出
3.56: LinkedList用Queue接口,可向上转型Queue
3.57: offer(),Queue插入到队尾,或都返回false
3.58: peek()和element()
3.59: poll()和remove()移除返回队头,队头为空poll()返回null,remove()抛出NoSuchElementException异常
3.60: 不鼓励将queue转型会LinkedList
3.61: PriorityQueue优先级队列
3.62: Comparator
3.63: Collection附属接口,表示其它若干个接口的共性而出现的接口
3.64: java.util.Abstract,Collection提供Collection的默认实现
3.65: 实现Collection就意味着需要提供iterator()方法
3.66: remove()方法是一个“可选操作”
3.67: Foreach与迭代器
3.68: 由于cs是一个Collection,能够与foreach一起工作是所有Collection对象的特性
3.69: 任何实现Iterable的类可以用于foreach语句中
3.70: implements Iterable
3.71: Iterable Class确实可以用于foreach语句中
3.72: System.getenv()返回一个Map,entrySet由Map.Entry构成的Set
3.73: 新程序不应该使用过时的Vector,Hashtable、Stack
3.74: 点线框表示接口,实线框表示普通的类、带有空心箭头的点线表示一个特点实现了一个接口
3.75: 异常参数
3.76: 终止模型恢复模型,不能回来继续运行,修正后继续运行一遇到错误调用修正方法或把try块放进while里,直到得到满意的结果
3.77: 创建自定义异常 extends Exception
3.78: 异常与记录日志 java.util.logging 工具将输出记录的日志中
3.79: e.getStackTrace()
3.80: StackTraceElement.getMethodName()
3.81: 重新抛出异常catch(){throw e;}
3.82: 异常链——捕获一个异常抛出另一个异常,保留前者信息
3.83: Java标准异常Throwable,RuntimeException 不受检查异常,使用finally进行清理
3.84: sw.off()方法的调用
3.85: 在try中return,finally都会执行
3.86: 异常的限制
3.87: 由于finally导致异常丢失
3.88: 构造函数阶段可能会抛出异常
3.89: 异常匹配,异常类的派生类也能捕获
3.90: 吞食异常try{}catch{}//Gulp!
3.91: 将异常抛出放函数后面交给控制台
3.92: throw newRuntimeException(e)避免吞食异常函数传递一个对引用的拷贝
3.93: Java不允许程序员重载任何操作符
3.94: append多次调用产生一大堆需要垃圾回收的中间对象
3.95: javap -c Concatenation生成JVM字节码
3.96: String.append()编译器自动引入了java.lang.StringBuilder类,用以构造最终的String,并为每个字符串调用一次StringBuilder的append()方法。
3.97: P284 - 286
3.98: 无意识地递归toString(){return "abc"+this+"\n";}
3.99: 如果内容没有发生改变,String的方法只是返回原对象的引用而已
3.100: 格式化输出printf,System.out.format() -> PrintStream、PrintWriter
3.101: java.uti.Formatter类处理 -> format("%s",x)
3.102: 格式化说明符format("%-15s %5s %10s\n","Item","Oty","Price");
3.103: String.format("(t%d,q%d)%s",tId,qId,message);
3.104: 一个十六进制转储(dump)工具P294
3.105: 正则表达式:一位数\\d,一个反斜线\\\\,换行制表符\n\t,一负号后跟一至多位数字 -?\\d+
3.106: String.matches(regex)
3.107: (-|\\+)? |表示或操作
3.108: split()依据正则表达式切开
3.109: split()重载版本允许设定分割次数
3.110: replceFirst和replaceAll
3.111: ^一行起始、$一行结束
3.112: 量词、贪婪型、勉强型?、占有型+
3.113: abc+和(abc)+
3.114: Pattern.compile()编译你的正则表达式
3.115: String -> Pattern -> matcher() -> Matcher对象、replaceAll()
3.116: static Pattern/compile()、matches
3.117: lookingAt()
3.118: Matcher.find()
3.119: charSequence
3.120: replaceFirst()和replaceAll()
3.121: reset()
3.122: 正则表达式与Java I/O
3.123: 扫描输入P309
3.124: numArray.split();
3.125: Scanner 大大减轻扫描输入的工作负担
3.126: (File对象、InputStream、String、Readable[BufferedReader])->Scanner
3.127: useDelimiter() 设置定界符,还有一个delimiter()方法返回定界符使用的Pattern对象
3.128: scanner.next(pattern);
3.129: StringTokenizer分割字符串
3.130: RTTI(Run-Time Type identification)基类指针引用指向派生类
3.131: Class.forName("ClassName")加载类常量FancyToy.class/TYPE,建议使用".class"的形式保持与普通类的一致性
3.132: 加载、链接、初始化
3.133: Class c = ClassName.class用于获取类应用调用静态变量
3.134: 新的转型语法 cast()方法
3.135: 类型转换前先做检查if(x instanceof Dog)
3.136: 如果程序中编写了许多的instanceof表达式则设计可能存在瑕疵
3.137: 类字面常量预加载一个Map
3.138: 动态instanceof,Map.Entry.getKey().isInstance(pet)
3.139: 递归计数,计算Class>中各类数量,isAssignableFrom()
3.140: 注册工厂,Factory extends Part>
3.141: instanceof和isInstance()生成的结果一样,会考虑继承
3.142: getClass().equals()和==结果一样,不会考虑继承
3.143: 反射、运行时的类信息
3.144: 反射,运行时的类信息,Class+java.lang.reflect类库,Field,Method,Constructor(Member接口),invoke(),getFields(),getMethods(),getConstructors()
3.145: Class->getMethods(),getConstructors()->Method和Constructor,解析其对象所代表的方法、获取其名字,输入参数以及返回值,动态代理,代理是基本的设计模式之一
3.146: Class1{Class2 c2;f(){c2.doSomeThing();}}
3.147: Proxy.newProxyInstance()创建动态代理P339
3.148: 可用interface NULL{}来代替空对象null
3.149: 模拟对象与桩
3.150: interface关键字允许程序员隔离构件,进而降低耦合性
3.151: 通过使用RTTI,发现a是被当做B实现的
3.152: 私有内部类
3.153: P352泛型,通常而言,我们只会使用容器来存储一个种类型的对象
3.154: 元祖tuple允许读取不允许存放
3.155: return new TwoFuple -> FiveFuple<...>(...)
3.156: 一个堆栈类下推推栈
3.157: net.mindview.util.Stack用一个LinkedList实现的
3.158: RandomList.select()
3.159: 泛型接口,生成器generator,专门负责创建对象的类
3.160: 实现Generator
3.161: 重写Iterable的Fibonacci生成器,不过,你并不是总能拥有源代码的控制权,并且除非必须这么做否则我们也不愿重写一个类
3.162: 或者创建一个适配器adapter来实现所需的接口
3.163: extends Fibonacci implements Iterable
3.164: iterator(){return new Iterator
3.165: 应该尽量使用泛型方法
3.166: static方法访问泛型得先成为泛型方法
3.167: public
3.168: 使用了泛型的函数可以识别各种类型
3.169: 泛型使用无需知参数
3.170: 编译器会为我们找出具体的类型称为类型参数推断
3.171: 相等f()被无限次地重载过
3.172: 编号一个工具类,包含各种各样的static方法,专门用来创建各种常用的(泛型)容器对象,类型推断只对赋值有效,传参无效
3.173: 解决传参问题
3.174: f(New
3.175: 泛型方法和可变参数列表能够很好地共存
3.176: public static
3.177: Generator
3.178: TupleTest.java
3.179: EnumSet.range()
3.180: Generator
3.181: 用泛型构造复杂模型
3.182: 擦除
3.183: ArrayList.class可以
3.184: ArrayList
3.185: ArrayList
3.186: 然而放String或Integer所得到的行为完全不同
3.187: 泛型类中Class.getTypeParameters()输出中发现的只是用作参数占位符的标识符,因此现实是,在泛型代码内部,无法获取任何有关泛型参数类型的信息——List
3.188: 擦除即泛型的类型无法在类中得知,但C++可以
3.189: 可以用
3.190: 希望代码能跨多个类工作时,使用泛型才有帮助
3.191: 迁移兼容性——泛化的客户端可以用非泛化的类库来使用
3.192: 编写泛型类时需要提醒自己“不,他只是一个Object”
3.193: 泛型可以表示没有任何意义的事物,String.class -> Class
3.194: 擦除在方法体中移除了类型信息,运行时的问题就是边界, P379-380
3.195: new T()无法实现,需要使用工厂,使类自带newInstance()方法构造
3.196: 泛型数组Generic
3.197: 边界
3.198: Fruit[] fruit = new Apple[10]正确List
3.199: flist = >具有任何从Fruit继承的类型的列表
3.200: 编译器有多聪明,只是传参类型为Object而已
3.201: 逆变,超类型通配符 super MyClass>、 super T>不能声明成
3.202: 放松了在可以向方法传递的参数上所作的限制,f(List
3.203: 协变,通配符P394
3.204: 无界通配符>泛型参数可以持有任何类型
3.205: 多个泛型类型参数的无界通配符,Object> ,?>
3.206: List>表示具有某种特定类型的非原生List,只是不知道类型,List