《java编程思想》读书笔记(上)(第1章 至 第13章)

来源:互联网 发布:手机数据误删怎么恢复 编辑:程序博客网 时间:2024/06/03 23:46

        最近比较无聊,在做毕业论文,但是想想毕业论文和我即将开始的工作好像没什么关系,即使我毕业论文做得再好,也不会对我有什么影响,还不如趁着现在还有点时间,看看书,准备准备即将开始的工作。


     我是在word中写好的,直接复制上来的,格式上有点不好看,然后编号上好像有一点点小问题,不过应该不影响阅读


1章:对象导论

1、在建立新类时,首先考虑用组合,而不是继承

2、有时需要在派生类中添加新的方法,即扩展接口,但是基类是无法访问派生类中的新方法的。

3、单根继承结构使得垃圾回收器的实现变得容易很多

4、异常处理并不是面向对象的特征尽管异常常被表示为一个对象,但异常处理在面向对象语言出现之前就有了

2章:一切都是对象

  1. 5不同的地方可以存储数据:栈、堆、寄存器、常量存储、非RAM存储

  2. 基本类型的数据不用new创建,存储于栈中

  3. 所有数值类型都有正负号,所以不要去寻找无符号的数值类型

  4. Boolean所占的空间大小没有明确定义,仅定义为能够取字面值truefalse

  5. 高精度计算用BigInteger类(支持任意精度的整数)和BigDecimal类(任意精度的定点数)

  6. java中数组会进行范围检查,是以每个数组上少量的内存开销及运行时的下标检查为代价的

  7. C/C++中可以将较大作用域的变量“隐藏”,但是java中不允许,编译错误

  8. 垃圾回收器,监视用new创建的所有对象,并辨别那些不会再被引用的对象

  9. 若类的某个成员是基本数据类型,即使没有初始化,java也会确保它获得一个默认值。但是,“局部”变量不适用,在某个方法中:{int x},那么x的值可能是任意值

  10. 字符串中每个字符的尺寸都是16位或2个字节,以此来提供对Unicode字符集的支持

  11. System.outout是一个静态PrintStream对象

  12. javadoc:只能处理/**….*/javadoc只能为publicprotect成员进行文档注释,privatedefault(包访问)的注释会被忽略掉

3章:操作符

  1. 方法中参数传递的是引用,所以方法内部改变将带到外部去

  2. Random rand = new Random(47);//如果没有传递参数,就以当前时间作为随机数生成器的种子;rand.nextInt(100)rand.nextFloat(100),下限为0,上限为我们传递的参数100【也可用nextLongnextDouble

  3. 一元减号用于转变数据的符号,而一元加号只是为了与一元减号对应,唯一作用仅仅是将较小类型的操作数提升为int

  4. 比较两个对象的内容是否相同,用equals()方法,但需要在类中覆写equals()方法。这个方法不适用于基本类型,类型用 == !=

  5. “与、或、非”操作只可用于布尔值,与C/C++不同的是:不可将一个非布尔值当做布尔值在逻辑表达式中使用

  6. 对浮点数的比较是非常严格的,即使一个数仅在小数部分与另一个数存在极微小的差异,仍认为它们是“不相等”的IntergerLong类的静态方法toBinaryString()可以将一个十进制、八进制等数以二进制显示出来

  7. java中,float f =1.39E-43f;代表1.39*10-43,后面的f是必要的,因为计算结果是double类型。long l = 200;后面不需要加L,因为“没有必要”

  8. 移位操作:

    左移操作:在低位补0

    右移操作:若符号为正,高位补0;若符号为负,在高位补1

    无符号右移>>>:无论正负,都在高位补0

    如果对byteshort值进行移位运算,先转换为int再移位

  9. while(x=y){

    }


这种错误不会出现在java中,因为java不会自动将int数值转换为布尔值,所以会出现编译错误

  1. 类型转换:窄化转换需要显示表示,扩展转化自动完成

  2. Math.round(arg):四舍五入

  3. Java中没有sizeof(),因为所有数据类型在所有机器上的大小都是相同的

  4. 对布尔值操作非常有限,只能赋予它truefalse,并测试它为真还是为假,不能将布尔值相加,或进行其他操作


4章:控制执行流程

  1. Math.random():产生01之间的一个double值(包括0,不包括1

  2. foreach用于数组和容器。

  3. returnbreakcontinue

  4. switch接受intchar,在java SE5后增加支持enum


5章:初始化与清理

  1. 重载的规则:每个重载的方法都必须有一个独一无二的参数类型列表

  2. 以返回值区分重载方法是不可行的,所以只有返回值不同的重载是不允许的

  3. 自己定义了构造器,则不会产生默认构造器,一般需要手动建立一个

  4. this只能在方法内部使用,表示对“调用方法的那个对象“的引用

  5. 当需要返回当前对象的引用时,可以用return this

  6. 在构造器中调用其他构造器,需要在第一行调用this(…),而且只能调用一个

  7. static方法的内部不能调用非静态方法,反过来可以,static的主要用途是通过类名来调用。static具有“全局函数“的语义,有人认为它不是面向对象的

  8. Java允许在类中定义finalize()方法,用于在垃圾回收时调用

  9. 只要程序没有濒临存储空间用完的那一刻,垃圾回收器是不工作的,对象占用的空间就总也得不到释放

  10. 垃圾回收只与内存有关:使用垃圾回收器的唯一原因是为了收回程序不再使用的内存

  11. 不要过多使用finalize()方法,因为往往很难得到调用。所以一般要创建其他的“清理“方法,并明确调用。如在finally块中调用

  12. 在堆上分配对象的代价十分高昂,垃圾回收器对于提高对象的创建速度,却具有明显的效果,java从堆分配空间的速度,可以和其他语言从栈上分配空间的速度相媲美

  13. 在堆中,没分配一个对象,它就往前移动一格,java的“堆指针“只是简单地移动到尚未分配的区域,当然,实际过程中在簿记工作方面还有少量额外开销,但比不上查找可用空间开销大

  14. 引用计数:每个对象都有一个引用计数器,当有引用连接到对象时,引用计数加1,当引用离开作用域或被置为null时,引用减1,当某个对象引用计数为0时,就释放其占用的空间。【引用计数从未被设计到java虚拟机中】

  15. 对任何“活“的对象,一定能追溯到其存活在栈或静态存储区中的引用。从栈和静态存储区开始,遍历所有的引用

  16. 停止-复制:先暂停程序的运行(所以不是后台回收模式),然后将所有存活的对象从当前堆复制到另一个堆中,没有被复制的都是垃圾

  17. 标记-清扫:在遍历引用过程中,找到活的对象就给对象设一个标记。全部标记工作完成后,清理工作开始,没有标记的对象将被释放,不会发生任何复制动作

  18. 一般会结合以上两种方法进行设计垃圾回收器

  19. 所有变量在使用时都应该得到初始化值,否则编译器错误

  20. 在类中定义一个对象的引用时,如果不将其初始化,它会获得一个null

  21. 在类内部,变量定义的先后顺序决定了初始化的顺序,即使变量定义散布于方法定义间,仍会在任何方法(包括构造方法)被调用前得到初始化

  22.  无论创建多少个对象,静态数据都只占用一份存储区域。static关键字不能应用于局部变量,因此它只能作用于于

  23. 即使没有显示使用static关键字,构造方法实际上也是静态方法

  24. Arrays.toString()方法是java.util包中的方法,它将产生一位数组的可打印版本

  25. 数组初始化:


Integer[] a ={new Integer(1), new Integer(2), new Integer(3),};


Integer[] b =new Integer[]{Integer(1),new Integer(2),new Integer(3)};


初始化列表的最后一个逗号可选


  1. 可变参数列表


static voidprintArray(Object… args)


  1. 枚举enum

    public enum Spiciness{

          NOT, MILD,MEDIUM, HOT, FLAMING

    }

    枚举类型的实例都是常量

    public class EnumOrder{

          public staticvoid main(String[] args){

               for(Spicinesss : Spiciness.values()){

       System.out.println(s+ “ordinal” + s.ordinal());

    }

    }

    }

    ordinal()表示某个特定enum常量的声明顺序,静态方法values(),按照声明的顺序产生由这些常量值构成的数组。

    enum还可用于switch语句结构中。

     

6章:访问控制权限

  1. 环境变量中CLASSPATH包含一个或多个目录,用作查找.class文件的根目录

    假设有类d:\DOC\java目录下com.liao.gate.Simple,则添加.;d:\DOC\Java

    但在使用jar包时,CLASSPATH路径应该写上jar包完整文件路径

  2. 如果一个类中的方法都是静态方法,则可以静态导入,static import …

    在类中就可以直接使用方法,不需要加类名

  3. public > protect >default > private

  4. 每个文件只能有一个public方法,且必须与类名相同,包括大小写。文件内完全没有public方法也是可以的

  5. 类既不可以是private也不可以是protect,只能是public和包访问权限

    如果不希望其他任何人对该类有访问权限,可以将所有构造器都指定为private


7章:复用类


  1. 最好的办法是除了内存以外,不能依赖垃圾回收器去做任何事,如果需要进行清理,最好是编写自己的清理方法,但不要使用finalize()

  2. 到底是该用组合还是继承,一个最清晰的判断方法就是问一问自己是否需要从新类向基类进行向上转型

  3. final关键字

    1final定义的变量是常量

    2final定义的方法不可以覆写

    3final定义的类不可以被继承

    4final使引用恒定不变,一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象,然而,对象其自身却是可以修改的。

    5java允许声明空白final,但一定要确保空白final在使用前必须被初始化(可以采取在构造器中初始化的方法初始化空白final

    6、类中所有的private方法都隐式地指定为是final的,但是由于无法取用private方法,所以也就无法覆盖它

    7、覆写只有在某方法是基类的接口的一部分时才会出现,如果方法为private,它就不是基类的接口部分,它仅是隐藏于类中的程序代码,只不过具有相同的名称而已

  4. 类的代码在初次使用时才加载,这通常是指加载发生于创建类的第一个对象之时,但是当访问static域或static方法时,也会发生加载

  5.  


8章:多态


  1. 将某个方法声明为final,可以有效地关闭动态绑定,或者说,告诉编译器不需要对其进行动态绑定

  2. 一旦知道java中所有方法都是通过动态绑定实现多态这个事实之后,我们就可以编写只与基类打交道的程序代码了

  3. 只有普通的方法调用可以是多态的,任何域访问操作都是由编译器解析,因此不是多态的。为Super.field和子类Sub.field分配了不同的存储空间

  4. 如果某个方法是静态的,它的行为就不具有多态性

  5. 继承与清理:当覆盖基类的dispose()方法时,务必记住调用基类版本的dispose()方法,否则,基类的清理动作就不会发生

  6. 导出类中接口的扩展部分不能被基类访问,因此,一旦我们向上转型,就不能调用那些新方法

  7.  


9章:接口


  1. 可以在interface关键字前面添加public关键字(但仅限于该接口在与其同名的文件中定义)。如果不添加public,则它只有包访问权限。接口可以包含域,但是这些域隐式地是staticfinal

  2. 使用接口的核心原因:为了能够向上转型和防止创建该类的对象

  3. 一般情况下,只可以将extends用于单一类,但是可以引用多个基类接口

  4. 因为放入接口中的域都是staticfinal的,所以接口就成为一种很便捷的用来创建常量组的工具。但在javaSE5后,使用enum较好

  5. 域不是接口的一部分,它们的值被存储在该接口的静态存储区域中

  6. 接口是实现多重继承的途径,而生成遵循某个接口的对象的典型方式就是工厂方法设计模式

  7.  


 

10章:内部类

11章:持有对象

  1. 通过使用泛型,就可以在编译器防止将错误类型的对象放置到容器中

  2. 添加一组元素到容器中:

    Arrays.asList()方法接受一个数组或是一个用逗号分隔的元素列表(使用可变参数),并将其转换为一个List对象

    List<Integer> listInt = newArrayList<Integer>(Arrays.asList(1,2,3,4,5));

    Collections.addAll()方法需要一个Collection对象,以及一个数组或一个用逗号分隔的列表,将元素添加到Collection中。

    collection.addAll()只能接受另一个Collection对象作为参数,因此较不如以上两个方法灵活,以上两个方法使用的都是可变参数

  3. 容器的打印:Arrays.toString()可以产生数组的打印

  4. Set的实现类:

    HashSet:使用散列表来存储元素,无顺序,这是最快的获取元素的方式

    TreeSet:按照比较结果的升序来保存对象

    LinkedHashSet:它按照被添加的顺序保存对象

  5. Map

    HashMap:使用散列表来存储元素,无顺序,这是最快的获取元素的方式

    TreeMap:按照比较结果的升序来保存对象

    LingkedHashMap:它按照被添加的顺序保存对象

  6. List

    ArrayList:它长于随机访问元素,但是在List中间插入和删除元素是较慢

    LinkedList:通过链表实现,方便插入和删除元素,随机访问较慢,但是它的特性集叫ArrayList

  7. 迭代器

    1、使用方法iterator()要求容器返回一个IteratorIterator将准备好返回序列的第一个元素

    2、使用next()获取序列中的下一个元素

    3、使用hasNext()检查序列中是否还有元素

    4、使用remove()将迭代器新近返回的元素删除

  8. 如果只是向前遍历List,并不打算修改List本身,那么你可以看到foreach语法会显得更加简洁

  9. ListIterator是一个更加强大的Iterator的子类型,它只能用于各种List类的访问,它可以双向移动。增加了hasPrevious()方法,而且也可以在List调用listIterator()时提供参数创建一个一开始就指向列表索引为n的元素处的ListIterator

  10. LinkedList,便于增加元素和删除元素,而且添加了可以使其用作栈、队列、双端队列的方法

  11. Stack,栈,主要有push()peek()pop()方法

  12. Set中最常被使用的事测试归属性,即可以很容易地询问某个对象是否在某个Set中,正因如此,查找就成为了Set中最重要的操作,因此,通常都会选择一个HashSet的实现,它专门对快速查找进行了优化

  13. Set<String> words = newTreeset<String>(new TextFile(“SetOperations.java”, “\\W+”))

    TextFile继承自List<String>,其构造器将打开文件,并根据正则将其断开为单词。排序是按照字典序的,因此大写和小写字母被划分到了不同的组中,如果要按照字母序,可以向TreeSet的构造器传入一个String.CASE_INSENTIVE_ORDER比较器:

    Set<String> words = newTreeset<String>(String.CASE_INSENTIVE_ORDER)

    words.addAll(new TextFile(“SetOperations.java”, “\\W+”));


 

  1. Map

    1containsKey ()containsValue()可以查看一个Map是否包含某个键或某个值

    2for(String s : words.keySet()){

               …words.get(s);

    }


    3for(Map.Entry entry: words.entrySet()){


          …entry.getKey();


          …entry.getValue();


}


  1. 新程序中不应该使用过时的VectorHashTableStack


12章:通过异常处理错误


  1. java的理念是:结构不佳的代码不能运行

  2. 当抛出异常时,有几件事随之发生,首先,将使用new在堆上创建异常对象;然后,当前的执行路径(它不能继续下去了)被终止,并且从当前环境中弹出对异常对象的引用。

  3. 所有标准异常类都有两个构造器:一个是默认构造器,另一个是接受字符串作为参数,以便能把相关信息放入异常对象的构造器

  4. 通常,异常对象中仅有的信息就是异常类型,除此之外不包含任何有意义的内容

  5. 异常处理理论上有两种模型,分别是终止模型和恢复模型

    终止:java支持终止模型,这种模型假设错误非常关键,以至于程序无法返回到异常发生的地方继续执行,一旦异常抛出,就表明错误已无法挽回,也不能回来继续执行。

    恢复模型:意思是异常处理程序的工作是修正错误,然后重新尝试调用出问题的方法,并认为第二次能成功。如果想要java实现类似恢复的行为,那么在遇见错误时就不能抛出异常,而是调用方法来修正该错误。或者,将try放进while循环中,就不断地进入try块,知道得到满意的结果

  6. 对异常来说,最重要的部分就是类名,所以一般类似class SimpleException extends Exception{}就足够用了

  7. 异常信息显示:

    String getMessage();

    String getLocalizedMessage();

    或者String toString()

    也可以用voidprintStackTrace()来输出调用栈轨迹

  8. Throwable类被用来表示任何可以作为异常被抛出的类,Throwable对象可分为两种类型:Error用来表示编译时和系统错误(除特殊情况外,一般不用我们关心);Exception是可以被抛出的基本类型

  9. 特例是RuntimeException,属于运行时异常的类型很多,它们会自动被java虚拟机抛出。

  10.  


13章:字符串


  1. 进行多个字符串连接时,尽量用StringBuilderjava SE5之前,用的是StringBuffer,它是线程安全的,因此开销较大些

  2. System.out.printf();

    System.out.format();

    以上两个方法等价,只需要一个简单的格式化字符串,加上一串参数,每个参数对应一个格式字符串

  3. java中,所有的格式化功能都有java.util.Formatter类处理,需要创建它的对象时,需要传递一个参数给它,告诉它最终结果的输出位置。

    Formatter f = new Formatter(System.out);

    f.format(“%s  %d”,name, age);

    d:整数型(十进制)|c:Unicode字符|b:boolean|s:String|f:浮点数(十进制)

    e:浮点数(科学计算)|x:十六进制整数|h:十六进制的散列码|%:字符“%

    如果需要控制空格与对齐,需要更精细的格式修饰符:

    %[argument_index$][flags][width][.precision]conversion

    默认右对齐,flags设置为“-”则左对齐,width定义最大尺寸

  4. 静态方法String.format()接受与前面format一样的参数,返回String类型

    其实内部也是创建了一个Formatter对象,然后将参数传入。这个方法比较便捷,代码也比较清晰

  5. 正则表达式:

    1、在其他语言中,\\表示:我想要在正则表达式中插入一个普通的(字面值)反斜线

    java中,\\的意思是:我要插入一个正则表达式的反斜线,所以其后的字符有特殊的意义。

    如果要表达一位数字,就是\\d;如果要插入反斜线:\\\\

    但是换行和制表符之类的只需单个反斜线,如\n\t

  6. -|\\+?     表示一个减号或者加号,或者没有

  7. String自带了split()方法用于将字符串从正则表达式匹配的地方切开,返回数组

    s.replaceFirst(“f\\w+”, “located”);

    s.replaceAll(“shrubbery|tree|herring”, “banana”)

正则表达式还没整理完。。。




0 0
原创粉丝点击