《Thinking in java》笔记

《thinking in java》引发的思考

关于java面向对象的思考——抽象、并发

thinking in java中1.1抽象过程的描述

问题空间——>解空间的映射(所有问题最终都是列表,所有问题最终都是算法,面向对象)

对象是现实世界的抽象,到解空间中很好表述

难点:如何在问题空间的元素 到 解空间的对象之间创造一一对应的映射

java中的不足——interface、abst?、 (1.必须先定义最高层[或者使用适配器方式]  2.类似的类如何高效的相互复用[比如你发现了一个物种,已经定义出了类,突然发现和它很类似的另一物种,需要添加属性,那是重新定义一个类吗,或者再已知类中添加属性,那后面又发现会重复添加下去,最后变得很复杂 还影响以前的实现?])

go中是如何做的——interface(从类中发现共性再抽象出更高层,现实中我们其实也是这样子的,我们发现了羊、牛等,然后抽象出了动物,而不是先定义动物后发现羊牛。而且最高层可以随意的抽象出任意多个来) struct(包含其它struct)

从面向对象的继承层次关系来看,这种组织结构确实有些奇怪。但是,当你了解了java.util 中更多的有关容器的内容后(特別是第17章中的内容),你就会看到除了继承结构有些奇怪外, 还有更多的问题。容器类库一直以来都是设计难题——解决这些难题涉及到要去满足经常彼此 之间互为牵制的各方面需求。因此你应该学会中庸之道。

一、对象导论

抽象过程:问题空间 -> 解空间 (对象)

每个对象都有一个接口:圆点符号链接一个消息请求

每个对象都是一个服务提供者

二、一切都是对象

所有对象都是通过引用去操作;String s只是创建一个引用,需要你去new创建对象赋值,否则使用它会产生运行时错误。

基本类型作为类成员会自动初始化默认值,但是在函数中定义时会像c++一样任意值。

对象自动释放。

static静态成员,和c++一样所有对象共享一个。

文件中必须有一个和文件名相同的类。

三 四、 操作法与控制流程

equals默认是引用比较,自己写的类需要覆盖该函数

基础类型自动向上转换,向下需要手动,否则编译器报错

五、初始化与清理

构造函数(没有创建,则编译器会为你创建一个默认无参的构造函数,如果有创建构造函数,则编译器不会再创建默认构造函数。构造函数其实是隐式的static)

方法重载(同名不同参,重载构造函数)

this作为非静态函数的第一个参数传入(构造函数中调用其他构造函数: this(arg1,arg2) 非构造函数中不能这么用)

自适应垃圾回收:标记清扫(碎片) + 停止复制(耗时)。自己需要特殊清理用finalize。

 

- 静态块初始化/实例初始化 :构造器之前执行(1.直接初始化 2.块初始化 3.构造函数)。

- 数组和对象一样,int[] a只是定义一个引用,需要a=new int[10]来初始化,此时数组元素是没有初始化的,对象数组也一样。

六、访问权限控制

1.public  2.protected(同一包内都可以访问)  3.private  4.不写:默认包访问权限(friendly)

1.让使用者更轻松 不用去关心那些private,2.封装变化,重新实现后,使用者不用更改

七、复用类

组合、继承(只有单继承extends)、代理

继承:is-a,组合:has-a

final成员:可以在构造函数及之前初始化(定义处、块、构造函数)

final参数:确保方法中不会去改该参数。

final方法:确保导出类不去改变该方法的实现,不会被覆盖。

final类:处于安全或设计考虑,不允许有子类

Vector->ArrayList, HashTable->HashMap使用后者,设计得更好

八、多态

多态:分离做什么和怎么做。将改变的事物和未变的事物分离开(例如:插件架构)

封装:通过合并特性和行为来创建新的数据类型

实现隐藏:通过将细节私有化,把接口和实现分离

【除了static和final方法(private也是final)都是默认动态绑定】

- final(private)无法覆盖,即无法多态,static是与类关联而非对象,也无法多态。

- 不要在构造器中调用方法,如果此方法被子类重载,创建一个子类对象时,会先调用基类的构造器,基类构造器中会调用子类重载后的方法,此时子类的构造器还没有执行,数据未初始化,如果再改方法中访问了数据成员,会造成bug。唯一能安全调用的是final(private)方法。

- 子类重载函数可返回协变类型(即子类重载函数的返回类型可以是基类返回类型的子类)。

- 继承与组合的选择:用继承表达行为间的差异,用字段表达状态的变化。

九、接口

- interface中的字段都是static & final & public,方法默认且必须是public。interface可以继承其他interface,接口继承可以是多继承。

- implements后可以跟多个interface,使用接口的核心原因:能够向上转型为多个基类。implements必须在extends之后,否则编译会报错。

- “确定接口是理想选择,因而应该总是选择接口而不是具体的类。”这其实是一种诱惑:

 

十、内部类

成员内部类(类似类成员)、局部内部类(类似局部变量)、匿名内部类(常用于事件回调函数)、静态内部类(类似类静态成员)

TODO

十一、持有对象  TODO11.7-11.11(具体每个容器用的时候看)

1. Collection

2. Map

3.Iterator:统一了不同容器元素的访问方式

- foreach与iterable

 

 

十二、异常

- RuntimeException可以不用捕获,而且运行过程中,java虚拟机也会抛出。

- 继承中,子类覆盖方法只能抛出基类方法中声明的那些异常(少于等于),以确保使用基类的地方能正常使用派生类。

- 构造器子类可以抛出任何异常,不受基类限制。

异常处理的重要原则:只有在你知道如何处理的时候才捕获异常。

异常处理的一个目的是:错误处理的代码同错误发生的地点相分离。

- 可用用RuntimeException来包装异常,来避免异常声明。

 

十三、字符串

- String对象是不可变的,所有修改操作都会生成一个全新的String对象,所以多个字符串相加会生成多个临时对象浪费性能(简单语法的编译器会用StringBuilder优化,但像for循环中是不行的)。

- StringBuilder是后引入的操作字符串,StringBuffer是线程安全的但是更费性能。

- javap -c 类名   在编译好的classes目录执行,生成JVM字节码来分析你的代码。

TODO13.6 正则表达式

十四、类型信息

Class.forName("Name") 加载类,

基本类型包装类有TYPE字段等价与基本类型的class:int.class == Integer.TYPE

泛化的class引用(主要是为了添加编译器类型检测):Class<Number>    Class<?>    Class<? extends Number>

list装多种类型:List< Class<? extends Number> >

instanceof,   Class.isInstance(),   Class.isAssignableFrom()

反射与RTTI的区别在于:反射.class文件在运行时才知道。

【14.6.1制作工具,22.GUI版本】使用反射获取某类的所有方法,而无需在jdk文档中翻阅繁杂的继承树。

可以利用反射调用私有类/内部类/私有方法等等(14.9)。

动态代理:写代理类时,不要要把每个代理函数都写一遍;通过反射实现不同类型的通用代理。

空对象:避免到处都是null判断。

总结:凡是可以使用多态的地方都应该使用多态,只有在必要时才使用RTTI或switch。

十五、泛型

编译器为你转型操作,并负责类型的正确性。

泛型接口/类,泛型方法,在能使用泛型的地方尽量使用泛型(分离类型和逻辑)

static方法不能访问泛型类的类型参数,所以要使它有泛型能力只能用泛型方法。

类型擦除:(new HashMap<String,String>()).getClass() 与 (new HashMap<Integer,String>()).getClass()相等;擦除会移除类型参数的信息,那么使用反射时都是拿不到这些信息的,如执行 arg instanceof T; new T()都会报错,解决办法有构造器传入Class参数/其他接口方法等。

泛型边界:class Generator<T extends String>{} 这样在类方法中T才可以调用String的方法。

TODO15.9~

十六、数组

十七、容器深入研究

十八、I/O系统

十九、枚举

编译器创建的enum类都是继承自Enum类。

常量、switch、添加新方法、覆盖枚举方法、实现接口、使用接口组织/分类枚举、枚举集合EnumSet/EnumMap、枚举常量各自的方法。

TODO 19.10~19.11

二十、注解

三种标准注解,四种元注解。

嵌套注解,注解不能继承。

TODO 20.3~

二十一、并发

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值