zoukankan      html  css  js  c++  java
  • 【Thinking in Java】读书笔记

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6480258.html

    第三章:操作符

    1:基本数据类型的比较用 ==、!=,引用类型的==、!=是针对地址的比较。适用于所有对象(引用类型)的比较函数是equals()。

    2:短路:判断条件只需有一条使得判别式为真或为假,余下的就不会再执行。比如:1||a op b,读取到1时即可判定为真,后面的不再进行执行。

    3:移位运算只能作用于int数据类型。其他类型要转为int才能进行移位。

    4:类型转换:低——>高,自动对齐;高——>低,强制转换。

    5:浮点数转换为int默认截尾(即直接去除小数部分),要四舍五入的话需要用到round()函数。

    第五章:初始化与清理

    1:以基本类型的参数不同进行重载的函数,在调用时容易由于数据类型的向上转换而造成混淆。在调用参数为基本数据类型的函数时,定义时所用参数的类型大于等于实际参数类型的函数都会被调用。比如:f(int i)、f(float i)、f(double i),在调用时传 f(5),则以上三个函数都被执行。所以,为了避免混淆,一般在实际调用时对参数进行窄化处理,显式声明数据类型。

    2:不能以返回值区分重载方法:编译器根据代码语境来进行重载方法的选择,但如果调用函数时只是在单独一行调用而没有赋值号,则无法区分所处环境需要什么返回类型,也就无法进行相应的调用了。

    3:默认构造器:如果自定义的类中没有构造函数,编译器会自动创建。而如果进行了构造函数的重载,则默认构造函数也需要自己定义。

    4:在构造函数中调用另一个构造函数,只需用 this.(参数) 即可。注意,这一句必须位于所定义的构造函数的最顶行。

    5:static方法没有this指针,因为static没有特定的对象,所以没有this调用。

    6:Java垃圾回收器只会回收new关键字分配内存的对象,并且只有在内存不够时才进行垃圾回收。那么在某些对象使用完后如果想要手动清楚,可以在对象的类中定义finalize()函数进行销毁操作。在使用完对象后调用finalize()方法即可。否则,存储空间不够话容易造成内存泄漏。

    7:垃圾回收器的工作:

        1)引用计数法:每个对象有一个引用计数器,每当有一处引用执行该对象时就加一。当某个对象的引用计数为0时,就释放这个对象。

        2)停止—复制法:先暂停程序的运行,然后将所有存活的对象复制到另一个堆,那么没有被复制的就是垃圾。

        3)标记—清扫法:遍历所有引用,每当找到一个存活的对象就给对象一个标记。在全部标记完成后,清理动作才开始,没有标记的对象全部被释放。

    8:类的每一个基本数据类型的成员都会有有一个初始值,默认为0;引用类型默认为null。当然,进行了初始化赋值则除外。

    9:enum类型的一个使用:用于switch(enum)—case ENUM_X。

    第六章:访问权限控制

    1:根据包路径唯一确定类。

    2:一个java源文件成为一个编译单元,一个编译单元内只能有一个public类。处于编译单元内的非public类主要为主public类提供支持,对包外是不可见的。

    3:在导入了不同包中的同名类时,需要用   完整的包路径.类名  来指定使用那个类。

    4:使用自己创建的工具类库(jar包):自己定义工具类,放入一个包中——把包路径添加到ClassPath下——在使用时,import包,创建对象调用方法即可。一切工具包都是从ClassPath根目录开始查询的,所以必须配置到ClassPath下。

    5:Java访问权限修饰词:

    6:类的访问权限:

    第七章:复用类

    1:代码复用的方法有两种:组合、继承。

    2:惰性初始化:在需要使用对象时才进行对象的初始化。

    3:Java不支持多继承,但可以纵向“多层继承”。如: B extends A,C extends B,D extends C。而在创建D时,是按A-B-C-D的顺序执行构造函数的。

    4:导出类构造函数中调用基类构造函数,只需用 super(参数) 即可。//区分重载构造函数中调用别的构造函数:this.(参数)

    5:代理:用组合包含一个类对象,然后定义一系列public方法供外界调用时,方法内部其实是用组合的对象调用其方法来实现的。这样做的目的是,不让外界访问到组合的私有类对象,起到保护作用。

    6:析构子类:在子类中自定义了类似与析构函数的方法时,切记要在子类的“析构函数”中调用父类的“析构函数”,否则子类对象销毁了而它指向的父类对象还在。因为创建子类时,是先创建它的父类再创建子类对象的(因为子类创建时需要调用父类的方法)。

    7:向上转型:用基类指向导出类对象,然后调用被导出类重写了的方法,但不能调用导出类新增的方法。

    8:final关键字:

        1)用final修饰的基本数据类型变量值不可以被改变;而final修饰的引用对象,其指向不能被改变,但是指向的对象的内容是可变的。

        2)函数的参数列表中,用final修饰的参数在函数中不能被修改。这在匿名内部类的使用时尤其有用,匿名内部类只可以使用函数所传内容但不能修改他们。

        3)final修饰方法:则继承该类的导出类中不能重写该方法。(类中private的方法都隐式地被指定为final的,所以子类中也无法覆盖它。也就是说,在子类中非private的方法才能被覆盖)

        4)final修饰类:被final修饰的类不允许被继承。

    9:所有的static代码在类加载时按照代码顺序依次初始化,而且只会初始化一次。只有就一直存在于内存中供调用。

    10:执行顺序:

        1)编译器加载类时执行:由父—>子顺序,按代码顺序把static代码依次加载到内存并进行初始化操作(赋值、计算、输出等);

        2)在子类被创建时执行:由父—>子顺序执行构造函数,调用相应方法;

    第八章:多态

    1:多态,也叫动态绑定,后期绑定,运行时绑定;

    2:再论向上转型的使用:基类提供调用的规范定义,导出类进行具体的实现。向上转型根据子类类型进行相应的方法调用;

    3:多态运行时分析方法:对于导出类运行时调用的到底是父类的成员、方法还是子类的,如何分析?我们可以把父类中的成员、函数复制到子类代码中去,然后把与子类同名的非private内容去掉(因为被子类中的同名内容覆盖了。而private的相当于没复制过来,此时子类中同名的内容相当于新增的),剩下的就是父类中在子类仅存的内容。然后根据运行时调用的成员、函数是属于父类部分还是子类部分即可进行相应调用并得出结果。

    4:父类中static修饰的方法在子类中不会被覆盖。所以子类对象调用时执行的是父类中该静态方法的代码。

    5:再论对象的清理:如果手动定义类对象的清理工作,我们需要在子类的“析构函数”中也调用父类的“析构函数”来清除子类引用的父类对象。但是如果创建子类时通过传递一个父类对象进来而进行的子类创建,那么有可能一个父类对象被多个子类对象引用,这样的话子类的“析构函数”就不是单纯的清除引用的父类对象了,而是改变父类对象的引用计数器并调用父类的“析构函数”。而父类的“析构函数”先检查引用计数器,为0才进行父类对象的清楚。

    6:协变返回类型:导出类中覆盖基类的方法时,返回类型可以是基类中同名方法的返回类型的子类。比如:A中f()返回X;B继承A重写f()返回Y,Y是X的子类。

    7:纯继承:导出类只重写了基类定义的方法,而没有增加任何内容。

    8:运行时类型识别(RTTI):

    第九章:接口

    1:接口用来建立类与类之间的协议(操作规范)。

    2:Java中的“多重继承”:一个类可以实现多个接口来组合多个行为。

    3:解耦:如果知道某事物应该成为一个基类,我们优先把它定义为一个接口。

    4:接口的继承:可以通过继承在新接口中组合多个接口。

    5:接口的常见用法:策略模式。一个接口定义一种行为,然后在定义类时根据需要来实现相应接口来“按需”组合多种行为。

    6:接口在设计模式的使用:适配器、工厂方法。

    第十章:内部类

    1:内部类可以使用外部类中的所有元素

    2:在拥有外部类对象之前是不能创建内部类对象的,因为内部类对象会暗暗连接到它的外部类对象上,所以创建内部类对象:new 外部类名.内部类()、外部类对象.new 内部类()。但是静态内部类(嵌套类)不需要,直接new 内部类名 即可。

    3:在内部类获取其所在外部类对象的引用: 外部类.this

    4:在方法内部定义匿名内部类来执行一次性的操作。而经过方法参数传进来的被匿名内部类使用的参数必须用final修饰,即:外部传进来的数据不能被匿名内部类修改

    5:嵌套类:声明为static的内部类。其没有指向外部类的引用,可以直接创建。但是同样地,也就无法在静态内部类中访问到非静态的外部类对象(因为无指针,无联系)。另外,静态内部类可以含义static数据和字段,而普通的内部类不能。

    6:接口内的类:可以在接口内定义静态内部类,以提供被实现接口的所有类所共用的方法。

    7:内部类的优势:内部类可以独立地继承一个类或实现一个接口,而不受外部类影响。而内部类右可以提供了给外部类对象调用。所以,一些不方便被外部类继承、实现的类、接口可以用一个内部类来继承、实现,外部类只需调用内部类的相应函数即可使用想要的功能。

    8:内部类继承:继承一个内部类需要用  extends 外部类.内部类  形式声明,并且在构造函数中要传递一个外部类对象进来,通过 外部类对象.super()  调用构造函数进行内部类构造函数的调用。

    9:被继承的类中的内部类不会被覆盖:当某个外部类被继承时,即使在子类中定义了一个同名的内部类,也不会覆盖掉父类中的内部类,因为两个处于各自的命名空间里。调用时默认调用父类中的内部类。如果想在子类中使用同名的内部类,用子类中内部类继承父类的内部类即可。

    11:内部类的文件命名:在编译java文件时,得到.class文件。文件名由  外部类$内部类1内部类2....class 组成。

    第十一章:持有对象(容器)

    1:Collection:List按照插入顺序保存元素,Set不能有重复元素,Queue按先进先出组织元素;

    2:要大量随机访问,用ArrayList;要经常插入删除,用LinkedList;

    3:Java中的队列和栈由LinkedList提供支持(底层是Linkedlist);

    4:HashMap提供快速访问(使用散列方式组织元素,无序),TreeMap保持按照“key”的排序状态来保存元素,LinkedHashMap保持元素按照插入顺序,又通过散列方法加快访问;

    5:HashSet提供最快查询,TreeSet保持元素处于排序状态,LinkedHashSet以插入顺序保存元素;

    6:添加一组元素创建collection:Arrays.asList(数组)、Collection.addAll(collection/元素列表)

    7:迭代器:遍历容器对象。Iterator只能沿着容器对象的内容单向移动遍历,使用hasNext()方法检测容器是否还有元素,使用next()方法获取下一个元素。“迭代器统一了对容器的访问方式。”

    8:双向迭代器(ListIterator):只能用于各种List类容器的访问,但它可以双向移动。可以通过 nextIndex()/previousIndex()前后移动,可以set(XX)改变当前元素,可以listIterator(n)指定迭代器从list的第n个结点开始遍历。

    9:foreach迭代器:一般用来遍历数组,但是也可以用来遍历collection容器。

    10:LinkedList实现栈:push()入栈,pop()弹出栈顶元素,peek()获取栈顶元素但不弹出;

    11:LinkedList实现队:Queue q=new LinkedList<E>();offer()入队,peek()/element()返回队首元素,poll()/remove()移除并返回队首元素。

    12:TreeSet使用红黑树存储元素,HashSet使用散列函数储存元素加快查询。

    13:Map可以返回它的keySet,然后用iterator遍历key时map.get(key)遍历map。

    14:优先队列PriorityQueue:下一个弹出元素是优先级最高的元素。可以制定Comparator来修改队列元素排序规则,offer()插入元素时自动按照优先级高低排序。

    第十二章:异常

    1:异常的根类是Throwable

    2:用try-catch捕获并处理异常。注意catch(exception)语句的设置:异常处理匹配遵循就近原则。异常处理系统会按照catch子句的代码顺序找到“最相近”的处理程序进行处理,而找到后就认为该异常以得到处理,不会再往下查找。所以我们应该按照从小到大的顺序捕捉,异常一旦被其中一环捕获了就不会再向下传递,在最后一个catch才用catch(Exception)捕捉所有类型的异常。

    3:异常信息栈轨迹:printStackTrace()打印“从方法调用处直到异常抛出处”的方法调用序列。

    4:抛出异常:throw 会把异常抛给上一级环境中处理,此时后面的catch语句将被忽略。所以,一般我们把抛出异常的catch子句放在最后。

    5:Throwable子类中,Error、Exception、RuntimeException提供了带参数的构造器,可以自定义异常提示信息。

    6:异常分两种:编译(静态)异常和运行时异常。静态异常在编码阶段就要进行捕获处理,而运行时异常是不可预料的,它没有被捕获的话就会一直往上传递直到main(),然后程序打印异常信息并退出。

    7:finally:无论try-catch语句发生了什么,finally子句都能运行。一般用来进行清理工作,比如关闭try子句中打开的文件连接、数据库连接等。注意:即使在try语句中进行了return,finally语句也会执行!

    第十三章:字符串

     1:字符串对象不可变,看起来修改字符串的实际上都是新建了一个全新的字符串对象。

    2:Java仅有的两个重载的运算符: +、+=都是用于连接字符串的。其实质是:编译器创建一个StringBuilder对象,然后把拼接的字符串append进来,最后生成一个新的String对象。

    3:格式化字符串输出:System.out.printf()和System.out.format()方法均可以进行字符串的格式化输出,类似与C语言的printf()函数,使用格式修饰符来表示字符串的哪个位置输出什么类型的数据,并在后面用相应类型的数据进行赋值输出。也可以用String.format()方法来返回一个格式化的字符串再用系统函数进行输出。

    4:split(regex)方法:字符串根据regex正则表达式进行分隔。

    5:正则表达式是按照最近匹配的,abc+是ab后面跟一个或多个c。想要序列匹配的话就用括号括起来,如(abc)+。

    6:常用正则表达式符号:[]表示范围、+表示1或多次,*表示任意多次。s空白符,S非空白符,d数字,D非数字,w词字符(a-z0-9),W非词字符:(大写则非)

    7:Pattern和Matcher:使用pattern=Pattern.complie(regex)编译正则表达式获得一个模式,使用Matcher c=pattern.matcher(str)对字符串以pattern模式进行检索。由matcher的find()、lookingAt()、matches()方法等获取检索结果。

    8:Scanner:扫描输入字符串,可以接收任意输入对象(file、inputStream、String)作为构造函数参数。默认scanner以空白符作为分词定界符,但也可以自定义定界符:

    scanner.useDelimiter("自定义定界符")

    9:使用正则表达式进行扫描:用scanner.next(pattern)扫描符号规则的输入。

  • 相关阅读:
    是否有人会想起
    春风下也有落叶
    to kongove:呵呵~是啊,偶尔吹得玩下,仅当娱乐而已……
    木头人の狂想
    夜行静思湖
    [学习标准库]math.h
    [学习标准库]ctype.h
    [学习标准库]stdio.h
    句子
    [学习标准库]assert.h
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6480258.html
Copyright © 2011-2022 走看看