Think in Java 读书笔记(二)(浓缩出精华_(:з)∠)_)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/breavo_raw/article/details/74940223

ok,继续接着之前的写~~~中间放上几张P站大神的画作和一首歌,请慢慢欣赏~(侵删)

第10章

1、可以将一个类的定义放在另一个类的定义的内部,这就是内部类。

2、如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须具体地指明这个对象的类型:OuterClassName,InnerClassName。

3、想要创建内部类的对象,必须使用外部类对象创建内部类对象。

4、匿名类不可能有构造器。

5、匿名内部类将返回值的生成与表示这个返回值的类的定义结合在了一起。p197

方法(){
    return new 对象名();
    变量;
    方法;
}(详见197)

6、对于匿名类而言,实例初始化的实际效果等同于构造器。
——(不能重载实例初始化方法)

7、使用匿名内部类编写工厂模式;p200

8、优先使用类而不是接口。 p201

9、如果不需要内部类对象与外围对象有联系,那么可以将内部类声明为static。
static 内部类的含义:
——1)嵌套类创建对象,不需要外围类对象。
——2)不能从嵌套类的对象中访问非静态的外围类对象。

10、接口中可以嵌套类,内部类甚至可以实现外部接口。p202

11、每个内部类都能独立的继承一个(接口的)实现,所以无论外围是否已经继承了某个接口的实现,对于内部类没有影响

12、内部类允许继承多个(非接口类型)类或抽象类。

13、内部类是面向对象的闭包。p205
——java通过内部类提供闭包功能。

14、继承内部类后构造器的写法:p212

class withInner{
    class Inner{}
}

class h extends withInner.Inner{
    h(withInner wi){
        wi.super();  // 构造器的写法
    }
}

14、使用局部内部类而不用匿名内部类的唯一理由:
——因为,有时候我们需要一个以命名的构造器,或者需要重载构造器,而匿名内部类只能用于实例初始化。

15、每个类都会产生一个”.class”文件,其中包含了如何创建该类型对象的的全部信息(此信息产生一个“meta-class“,叫做class对象),而内部类也必须产生一个.class文件以包含他们的class对象信息。p215

16、第10章总结 p215

第11章

1、如果一个程序只包含固定数量且其生命周期都是已知的对象,那么这是一个非常简单的程序。

2、ArrayLists p216 (add( ),get( ),size( ))

3、@SuppressWarnings 注解及其参数抑制了警告信息。p217

4、泛型不仅仅用于确切的类型,向上转型同样适用于泛型
——也就是说,你可以将基类的子类型添加到指定被保存为基类的对象的容器。p218

5、collection: 一个独立的元素的序列,这些元素服从一条或者多条规则。
Map:一组成对的”键值对“对象,允许你使用键来查找值。

6、一个合理的做法:创建一个具体类的对象,将其转型为对应的接口,然后在其余的代码中都使用这个接口。
e.g.
List<...> s = new ArrayList<>();
但有时候向上转型并非完全有用。p219

7、List:ArrayList,LinkedList
——set:Hashset 是最快获取元素的方式。
——Treeset: 按照比较结果升序保存对象。
——LinkedHashset: 按照被添加的顺序保存对象。
——Map:HashMap 描述同set
——TreeMap:
——LinkedHashMap:

8、List的一些方法的描述(contains( ),remove( ),indexof( )等)p223

9、优化是一个很棘手的问题,最好的策略就是置之不顾,知道你发现需要担心它了。

10、适用于不同容器类型的通用编码设计模式(迭代模式)p226

11、一个迭代对象(Iterator)的作用;p226

12、迭代器操作的真正威力,能将遍历序列的操作与底层的结构分离;

13、Listiterator p227

14、NoSuchElement Exception p228

15、一个Linkedlist具有能有实现栈的所有功能和方法,但有时这不如一个真正的“栈”来的实在。(e.g.一个简单的实现,p230)

16、set中用的比较多是Hashset,它对专门快速查找进行了优化。

17、继承与多态的典型应用:表现不同的行为;p231

18、队列(先进先出)是指在给定的一组队列中的元素的情况下,确定一个弹出队列元素的规则。p237

19、先进先出声明下一个元素应该是等待时间最长的元素。
——优先级队列声明下一个弹出元素是最需要的元素(具有最高优先级)p237

20、如果你创建了任何实现Iterable的类,都可以将它用于foreach语句中;p241

21、在java中,map不是iterable类型 p242

22、尝试把数组当作一个Iterable参数会导致传递失败。这说明不存在任何从数组Iterable的自动转换,你必须手工执行这种转换。

23、当你有一个接口并需要另一个接口时,编写适配器就可以解决问题。p243

24、容器不能持有基本类型,但可以自动包装。

25、各种Queue以及栈的行为,由linkedList支持。p245

26、新程序中不应该使用过时的vetor,Hashtable和 stack。

27、第11章总结。

休息一下吧,看看美图吧~
Fgo同人图,作者lack@3日目東プ34a(点击查看作品)
这里写图片描述

第十二章

1、Java的基本理念“结构不佳的代码不能运行。”p248

2、如果不使用异常,那么就必须检查特定的错误,并在程序的许多地方去处理它,而如果使用异常,那就不必在方法调用时进行检查,因为异常几只能够捕获这个错误,并且,只需要在一个地方处理错误。

3、异常情形,是指阻止当前方法或作用域继续执行的问题。

4、抛出异常,把错误信息传播到了一个更大的环境中。p249

5、异常是的我们可以将每件事都当作一个事物来考虑。

6、异常也是对象(在异常类中);p250

7、异常处理程序紧跟在try块之后,以关键字catch表示。

try{
    ...
}catch(type2 id2){
    ...
}catch(type2 id3){
    ...
}  // 250

8、异常处理理论上由两种模型:①(Java支持)终止模型
————————————— ②恢复模型 (不是很实用,导致的耦合难以处理)p251

9、异常与记录日志(Java.util.logging) p253

10、环境越大的异常越应该放在末尾(最大的是基类Exception),以防止‘其他更具体的类’失去了处理的机会。

11、调用栈,打印栈轨迹显示了“把你带到异常抛出点”的方法调用。p257

12、重新抛出异常;p258

13、异常都是用new在堆上创建出来的对象,所以辣鸡回收器会自动把他们清理掉。

14、异常链;p260

15、Throwable 这个java类被用来表示任何可以作为异常被抛出来的类,可以分为两种类型:
——①Error:表示编译时和系统错误
——②Excption:可以被抛出的基本类型

16、RuntimeException(运行时异常) p263
——这种异常属于错误,将被自动捕获,就不用你亲自动手了。

17、只能在代码中忽略RuntimeException(及其子类)类型的异常,其他类型异常的处理都是由编译器强制实施的。究其原因,RuntimeException,代表的是,编程错误:
——1)无法预料的错误。比如你控制范围之外传递进来的null引用。
——2)作为程序猿,应该在代码中进行检车的错误。p264

18、①对于没有垃圾回收和析构函数调用机制的语言来说,finally非常重要,他能使程序猿保证,无论try块中发生了什么,内存总能得到释放。
——②对于java这种,finally的作用体现在把除内存之外的资源恢复到初始状态(文件,网络链接,screen上的图形等等)。p265

19、关于异常的一点缺憾。p268

20、finally会在每次完成构造器之后都执行一遍。p273

21、也许你曾想过,使用finalize( )清理资源,但你永远不会知道finalize( )有没有被调用。p273

22、Java的缺陷之一:除了内存清理之外,所有的清理都不会自动发生。

23、一种通用的清理惯用法,在构造器不抛出任何异常时也应该运用,其基本规则,在创建要清理的对象后,立即进入一个try-finally语句块;p273

24、异常匹配:抛出异常的时候,异常处理系统会按照代码的书写顺序找出“最近”的处理程序。

25、异常处理就像一个“活门”,使你能放弃程序正常执行的序列。当异常的情形发生的时候,正常的执行已经变的不可能或者不需要了。

26、Java,C++:强静态类型;p277
——C:弱类型

27、异常说明潜在的两种意思:①我的代码会出现这种异常,这由你来处理。
————————————— ②我的代码忽略了这种异常,这也由你来处理。

28、被检查的异常与程序规模之间的问题。p278

29、异常的使用指南;p281

30、异常处理有报告和恢复两种功效,其精髓在于报告。p281

31、第12章总结。p281

第13章

1、可以证明,字符串操作是计算机程序设计中最常见的行为。p283

2、string对象是不可变的,string类中每一个看起来会修改string值的方法,实际上都是创建了一个全新的string对象。

3、对于一个方法而言,参数是为该方法提供信息的,而不是想让方法改变自己的。

4、“+”对于string的意义(重载)p284

5、使用“+”连接字符串时,编译器内部会自动引入stringBuilder类。p285

6、stringBuilder是SE5引入的,之前用的是StringBuffer,后者是线程安全的。(开销更大)

7、string对象的一些基本方法。

8、插入数据时,如果想要控制空格对齐,你需要更精细复杂的格式修饰符。p291

9、Java正则表达式;p295

10、split( );p305

11、第13章总结;p312

再贴一张~
ジャンヌオルタ[花魁] 作者 猫鍋蒼
这里写图片描述

第14章

1、运行时类型信息使得你可以在程序运行时,发现和使用类型信息。p313

2、RTTI(Runtime Type Identification)

3、Java是如何让我们在运行时识别对象和类信息的。主要有两种方式:
①:一种是RTTI(其实这是C++的概念,书中没提到),运行时,识别一个对象的类型。
②:另一种是反射机制;p313

4、基类的方法在所有派生类中被覆盖,并且由于它是被动态绑定(后期绑定)的,所以即使通过泛化的调用,也能产生正确的行为,这就是多态

5、多态是面向对象编程基本目标。p314

6、类是程序的一部分,每个类都拥有一个class对象,换言之,每当编译成了新类,就会产生一个class对象(更恰当的说,是被保存在一个同名的.class文件中)

7、类加载子系统实际上包含一条类加载器的链,但是只有一个原生类加载器;加载可新类;p315

8、所有的类都是在对其第一次使用时,动态加载到JVM的。
——当程序创建第一个类对象的静态引用时,就会加载这个类。这证明构造器也是类的静态方法。
——Java程序在他开始运行之前并非被完全加载,其各个部分实在必须时才加载的。(基本都是之前的回顾)p315

9、class对象仅在需要的时候才被加载,static初始化是在类加载时进行的。p316

10、class.forname( )是取得class对象的引用的一种方法,它返回一个class对象的引用;p316

11、如果class.forname()找不到你要加载的类,会报classNotfoundException;p316

12、另一种生成class对象的引用的方法,类字面常量;p318
e.g. 类名.class
优点:更简单,更安全

13、Type字段 p318

14、使用“.class”来创建class对象的引用时,不会自动地初始化该class对象;p319

15、为了使用类而做的准备工作实际包含三个步骤:
——1)加载:由classloder执行,该步骤将查找字节码,并从这些字节码中创建一个class对象。
——2)链接:在链接阶段将验证类中的字节码,为静态域分配空间,并且如果必须的话,将解析这个类创建的对其他类的所有引用。
——3)初始化:如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块。

16、static final是一个“编译期常量”,那么该值不需要初始化就能够被读取。
但是如果将一个域设置为static final的话,则上述行为无法得到保障。p320

17、如果一个static域不是final的话,那么在访问之前首先需要进行链接(为这个域分配空间)和初始化(初始化该存储空间)p320

18、通配符就是“?”,表示“任何事物”。p320
——“?”可以解决泛型类的问题。

19、”?”配合“extend”p321

20、Java中RTTI的形式包括:
——1)传统的类型转换,如“shape”,由RTTI确保类型转换的正确性,如果执行了错误的类型转换,就会抛classCastException异常。
——2)代表对象类型的class对象。通过查询class对象可以获取运行时所需的信息;p323

21、一般情况下,查找某州类型,可以使用instanceof来计数所有对象。

22、一种方法,可以随机创建不同类型的宠物(有意义的实现);p325

23、class.isInstance方法提供了一种动态测试对象的途径。p329

24、注册工厂(又见工厂模式);p331

25、instanceof 与 class 的等价性与区别;p333

26、如果不知道某个对象的确切类型,RTTI可以告诉你,但是有一个限制:“这个类型在编译时必须已知,这样才能使用RTTI。”p334

27、反射提供了一种机制——用来检查可用的方法,并返回方法名。
——Java通过JavaBeans提供了基于构件的编程架构。

28、远程方法调用(RMI)是人们需要在运行时获得类的信息的另一个动机(分布式计算)。p335

29、class类与java.lang.reflect类库一起对反射的概念进行了支持。p335
——get()——>字段
——set()——>字段
——invoke()——>方法
匿名对象的类信息就能在运行时被完全的确定下来,在编译时不需要知道任何事情。

30、用反射与一个未知模型的对象打交道时,JVM只是简单的检查对象,看它属于哪个特定的类(就像RTTI那样)。
关键在于,用它做其他事情之前,必须先加载那个类的class对象
对于RTTI和反射机制来说.class文件是必不可少的。
1)RTTI是在编译时打开和检查.class文件
2)而反射则是在编译时无法获得.class文件的情况下,在运行时打开和检查.class文件。p335

31、反射可以用来支持对象序列化和JavaBean。p335

32、反射机制提供了一种方法,使我们能够编写可以自动展示完整接口的简单工具。p335

33、代理是基本的设计模式之一,它是你为了提供额外的不同的操作,而插入的用来代替“实际对象”的对象。p337

34、一个简单的代理结构。p337

35、设计模式的关键就是封装修改——因此你需要修改事物以证明这种模式的正确性。

36、动态代理的简单实现。p338

37、动态代理可以将所有调用重定向到调用处理器。p339

38、interface关键字的一种重要目标就是允许程序媛隔离构件,进而降低耦合性。但是通过类型信息,这种耦合性还是会传播出去——接口并非是对解耦的一种无懈可击的保障。p346

39、通过使用反射,可以到达并调用所有方法,甚至是private的方法!p348

40、面向对象编程语言的目的是让我们在凡事可以使用的地方都使用多态机制,只在必要时使用RTTI。p350

41、第14章总结。
这里写图片描述

最后,一首好听的日式RNB分享给大家

这里写图片描述

猜你喜欢

转载自blog.csdn.net/breavo_raw/article/details/74940223