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)扫描符号规则的输入。

  • 相关阅读:
    Java实现 LeetCode 69 x的平方根
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 68 文本左右对齐
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 67 二进制求和
    Java实现 LeetCode 66 加一
    Java实现 LeetCode 66 加一
    CxSkinButton按钮皮肤类
  • 原文地址:https://www.cnblogs.com/ygj0930/p/6480258.html
Copyright © 2011-2022 走看看