• ThinkInJava4读书笔记之第一章对象入门


         那句话怎么说来着,原句记不住了好像是出来混的迟早要还的。话说当初学校刚开Java课程,自己没有好好学啊,后来直接做了jsp和servlet,然后学了SSH框架和Extjs、jQuery,接着是mybatis(ibatis)、freemarker、springMVC。在学校实验室项目也做了一些,这些框架也都用过,有空的时候也读过ThinkInJava、EffectiveJava和深入Java虚拟机等经典书籍,设计模式的书也看过一本,但是没有认真做笔记进行总结,所以效果不大啊。现在重新阅读经典书籍,把笔记整理一下,希望能够对Java有一个深入的认识。

         Java中的类边界关键字

         Java采用三个显示关键字以及一个隐式关键字来设置类边界:public、private、protected以及隐式的friendly,若未明确指定其他关键字,则默认为后者。

         继承最终会以创建一系列类收场,所有类都建立在统一的接口基础上。对这样的一系列类,我们要进行的一项重要处理就是将衍生类的对象当做基础类的一个对象对待。这样就只需编写单一的代码,令其忽略类型的特定细节,只与基础类打交道。如通过继承添加了一种新类型,那么为新类型编写的代码会像在旧类型里一样良好工作,程序具备了扩展能力具有扩展性。

     动态绑定

         将一条消息发给对象时,如果并不知道对方的具体类型是什么,但采取的行动同样是正确的,这种情况就叫作“多形性”(Polymorphism)。对面向对象的程序设计语言来说,它们用以实现多形性的方法叫作“动态绑定”。编译器和运行期系统会负责对所有细节的控制;我们只需知道会发生什么事情,而且更重要的是,如何利用它帮助自己设计程序。

     抽象的基础类和接口

        abstract ---设计程序时,我们经常希望基础类只为自己的衍生类提供一个接口。即我们不想其他任何人实际创建类的一个对象,只能上溯造型成它,以便使用它们的接口,为达到这个目的需要把那个类变成“抽象”的。abstract关键字描述一个尚未实现的方法。子类要么实现父类中未实现的抽象方法,要么也声明为abstract类。

         interface接口将抽象类的概念更延伸了一步,它完全禁止了所有的函数定义。接口可以继承其他接口,不能继承普通类或abstract类。接口中可以定义属性,但是static final的。

    对象的创建和存在时间

         C++注重程序的执行效率,允许程序员做出选择。存储以及存在时间可在编写程序时决定,只需将对象放置在堆栈中或者静态存储区即可。这为存储空间的分配和释放提供了一个优先级。同时这牺牲了灵活性,因为编写程序时,必须知道对象的准确数量、存在时间以及类型。

         另一个方法,在内存池中动态创建对象,该内存池也叫堆或者内存堆。除非进入运行期,否则不知道到底需要多少个对象也不知道它们的存在时间有多长,以及准确的类型。这些参数都在程序正式运行时才决定。若需要一个新对象,只需在需要它的时候在内存堆里简单地创建它即可。由于存储空间的管理是运行期间动态进行的,所以在内存堆里分配存储空间的实际避灾堆栈里创建的时间长。在堆栈里创建存储空间一般只需要一个简单的指令,将堆栈指针向下或向上移动即可。由于动态创建方法使对象本来就倾向于复杂,所以查找存储空间以及释放它所需的额外开销不会为对象的创建造成明显影响,而更大的灵活性对于常规编程问题的解决是至关重要的。

    单根结构

         单根结构中的所有对象都有一个通用的接口,所有它们最终都属于相同的类型。单个结构中的所有都可以保证拥有一些特定的功能。一个单根结构,加上所有对象都在内存堆中创建可以极大简化参数的传递。Java中的基础类为Object,所有的对象都有一些相同的函数,如hashCode()等。

         利用单根结构,我们可以很方便地实现一个垃圾收集器。与此有关的必要支持可安装于基础类中,而垃圾收集器可将适当的消息发给系统内的任何对象。如果没有这种单根结构,而且系统通过一个句柄来操纵对象,那么实现垃圾收集器的途径会有很大的不同,而且会面临许多障碍。由于运行期的类型信息肯定存在于所有对象中,所以永远不会遇到判断不出一个对象的类型的情况。

    集合库与方便使用集合

         为了使这些集合能够重复使用,或者“再生”,Java 提供了一种通用类型“Object”。单根结构意味着、所有东西归根结底都是一个对象”。所以容纳了Object 的一个集合实际可以容纳任何东西。这使我们对它的重复使用变得非常简便。为使用这样的一个集合,只需添加指向它的对象句柄即可,以后可以通过句柄重新使用对象。但由于集合只能容纳Object,所以在我们向集合里添加对象句柄时,它会上溯造型成Object,这样便丢失了它的身份或者标识信息。再次使用它的时候,会得到一个Object 句柄,而非指向我们早先置入的那个类型的句柄。这时我们需要用到造型(Cast),下溯造型成一种特殊的类型。这种造型方法叫做“下溯造型”(Downcasting)。假如下溯造型成错误的东西,会得到我们称为“异常”(Exception)的一种运行期错误。下溯造型和运行期检查都要求花额外的时间来运行程序,而且程序员必须付出额外的精力。

    清楚时的困境,由谁负责清除

         每个对象都要求资源才能“生存”,其中最令人注目的资源是内存。如果不再需要使用一个对象,就必须将其清除,以便释放这些资源,以便其他对象使用。如果要解决的是非常简单的问题,如何清除对象这个问题并不显得很突出:我们创建对象,在需要的时候调用它,然后将其清除或者“破坏”。但在另一方面,我们平时遇到的问题往往要比这复杂得多。

         在Java 中,垃圾收集器在设计时已考虑到了内存的释放问题(尽管这并不包括清除一个对象涉及到的其他方面)。垃圾收集器“知道”一个对象在什么时候不再使用,然后会自动释放那个对象占据的内存空间。采用这种方式,另外加上所有对象都从单个根类Object 继承的事实,而且由于我们只能在内存堆中以一种方式创建对象,所以Java 的编程要比C++的编程简单得多。(在Java规范中并没有指定一定要使用垃圾收集器回收内存,只规定要使用某种方法进行内存回收,具体实现的方法由Java虚拟机的实现者决定)。

    垃圾收集器对效率和灵活性的影响

         在C++中,我们可在堆栈中创建对象。在这种情况下,对象会得以自动清除(但不具有在运行期间随心所欲创建对象的灵活性)。在堆栈中创建对象是为对象分配存储空间最有效的一种方式,也是释放那些空间最有效的一种方式。在内存堆(Heap)中创建对象可能要付出昂贵得多的代价。如果总是从同一个基础类继承,并使所有函数调用都具有“同质多形”特征,那么也不可避免地需要付出一定的代价。但垃圾收集器是一种特殊的问题,因为我们永远不能确定它什么时候启动或者要花多长的时间。

    异常控制

         在Java 中,异常控制模块是从一开始就封装好的,必须使用它。如果没有自己写一些代码来正确地控制异常,就会得到一条编译期出错提示。这样可保证程序的连贯性,使错误控制变得更加容易。

    多线程

         Java 的多线程机制已内建到语言中,这使一个可能较复杂的问题变得简单起来。对多线程处理的支持是在对象这一级支持的,所以一个执行线程可表达为一个对象。Java 也提供了有限的资源锁定方案。它能锁定任何对象占用的内存(内存实际是多种共享资源的一种),所以同一时间只能有一个线程使用特定的内存空间。为达到这个目的,需要使用synchronized 关键字。其他类型的资源必须由程序员明确锁定,这通常要求程序员创建一个对象,用它代表一把锁,所有线程在访问那个资源时都必须检查这把锁。

  • 相关阅读:
    生命中的另一口井
    sqlldr使用小记
    字节单位介绍
    《Java虚拟机》随笔记01
    Python生成器实现杨辉三角打印
    什么是递归?用十进制转二进制的Python函数示例说明
    Python的filter与map内置函数
    Python内置函数property()使用实例
    Python装饰器的理解
    Python迭代与递归方法实现斐波拉契数列
  • 原文地址:https://www.cnblogs.com/waimai/p/2951239.html
Copyright © 2020-2023  润新知