首页 > 编程语言 > 详细

Head First Java(第二版)——总结

时间:2021-05-13 10:01:20      阅读:10      评论:0      收藏:0      [点我收藏+]

一、观后感  

  花了几天把这本书看完了,其实说实话,看完的收获跟预期的相比是有落差的,一方面是因为这第二版的出版时间太久了,里面有些东西其实现在不怎么用到了,像Swing这些,另一方面也是可能因为自己对Java也是有些了解,所以看完这本书的整体收获并不是那么大。但感觉里面的一些插图还是蛮有意思的,有一些配图感觉就是公然开车O(∩_∩)O。刚接触Java的一些朋友可以考虑看一下吧,不像那些纯技术的书那般枯燥。


二、各章节摘取的知识点

  下面把书中个人感觉有益或者是稍微有些遗忘的一些知识点记录下来

  1、进入Java的世界

    这里简单地先举例一些用Java编写的简单程序,类似于if,while,for,感觉比较有看点的就是最后的话题讨论——编译器与JVM争辩谁比较重要:通过“争辩”的方式介绍了编译器和Java虚拟机的作用。

  2、拜访对象村

      main()的两种用途:(1)测试真正的类;(2)启动你的Java应用程序

      面向对象设计扩展功能不需改动之前已经测试好的程序代码 

  3、认识变量

      变量名称必须以字母、下划线(_)或$符号开头,不能以数字开头,同时避开Java保留字

  4、对象的行为

      (1)类所描述的是对象知道什么与执行什么

      (2)Java是通过值传递的,也就是说通过拷贝传递(好处,举例如果我们有一个get方法获取类中某一个引用对象,然后这时我们修改get获取的对象的指向的话,这时如果不是值传递,类中的这个对象就被恶意篡改了,代码(在某个方法中):Obejct obj = A.getSomething();obj = new Object();)

      (3)封装:将类的属性私有化,对外提供可以访问该属性的公有方法,在方法中对修改属性作出一定的限制,从而达到数据的安全性,防止数据被恶意篡改。

      (4)实例变量(声明在类内)永远都会有默认值,如果没有明确的赋值给实例变量或者没有调用setter,实例变量还是会有值,局部变量(声明在方法中)就必须显性赋值

  5、超强力方法

       无

  6、使用Java函数库

    无

  7、继承与多态

      (1)继承下来的方法可以被覆盖掉,但实例变量不能被覆盖掉。

    (2)为什么会作出标识final的类?这样有什么好处?

      需要安全的时候——确保方法都会是你写的版本,此时就需要final。

  8、深入多态

    Object有两个主要的目的:作为多态让方法可以应付多种类型的机制,以及提供Java在执行期对任何对象都有需要的方法的实现程序代码(让所有的类都会继承到)。有一部分的方法是与线程有关。

  9、对象的前世今生

     (1)大部分的人都是使用构造函数来初始化对象的状态,也就是说设置和给对象的实例变量赋值。

     (2)构造函数应该是公有的吗?

       不,构造函数可以是公有的、私有或者不指定的

    (3)执行new的指令是个重大事件,它会启动构造函数连锁反应,还有,就算是抽象的类也有构造函数,虽然它不能对抽象的类执行new操作,但抽象的类还是父类,因此它的构造函数会在具体子类创建出实例时执行

    (4)父类的构造函数必须在子类的构造函数之前结束,这里举例了“小孩能够在父母之前出生吗”这个例子,子类对象可能需要动用到从父类继承下来的东西,所以那些东西必须要先完成。

    (5)super()与this()不可兼得

  10、数字与静态

    (1)静态变量的作用:被同类的所有实例共享的变量

    (2)例题:

public class TestBox{

    Integer i;
    int j ;

    public void go(){
        j = i;
        System.out.println(i);
        System.out.println(j);
    }

    public static void main(String[] args) {
        TestBox test = new TestBox();
        test.go();
    }

}        

 

      运行结果:空指针异常

      技术分享图片

   11、异常处理

    (1)假设你调用了一个不是自己写的方法,该方法执行某些有风险的任务,可能会在运行期间出状况,你必须认识到该方法是有风险的,你得写出可以在发生状况时加以处理的程序代码,未雨绸缪。

    (2)不是由编译器检查的RuntimeException的子类被称为检查异常

    (3)异常处理规则:只带有finally的try必须要声明异常(也就是在方法处throws这个异常)

  12、图形用户接口

    内部类可以使用外部所有的方法与变量,就算是私用的也一样。

  13、运用Swing

    无

  14、序列化和文件的输入/输出

    (1)当对象被序列化时,被该对象引用的实例变量也会被序列化,且所有被引用的对象也会被序列化

    (2)整个对象版图都必须正确地序列化,不然就得全部失败。如果某实例变量不能或不应该被序列化,就把它标记为transient(瞬时)的。

    (3)为什么有些变量不能被序列化?

        可能是设计者忘记实现Serializable,或者动态数据只可以在执行时求出而不能或不必存储

    (4)为什么我写过不需要序列化的类

        也许是因为安全性的理由让你不想把密码对象存储在文件上,或者某些对象的存储是没有意义的。

    (5)如果我使用了一个不能序列化的类,我是否能把它给子类出一个标记为可序列化的类

        可以,如果该类是可以被继承(没有被标记为final),你就可以制作出可被序列化的子类。

    (6)静态变量会被序列化吗

        不会,要记得static代表“每个类一个”而不是“每个对象一个”,当对象被还原的时候,静态变量会维持类中原本的样子,而不是存储时的样子

    (7)缓冲区的奥妙之处在于使用缓冲区比没有使用缓冲区的效率更好,如果直接使用FileWriter这种方式会花费额外的成本,每趟磁盘操作都比内存操作要花费更多时间,通过BufferedWriter可以暂存一堆数据,然后到满的时候再实际写入磁盘,这样就可以减少对磁盘操作的次数。

   15、网络与线程

     (1)TCP端口只是一个16位宽、用来识别服务器上特定程序的数字,如果没有端口号,服务器就无法分辨客户端是要连到哪个应用程序的服务。

     (2)新建线程的三个状态:

        i)新建:Thread t = new Thread(r);Thread的实例已经创建,但还没有启动,也就是说,有Thread对象,没有执行中的线程。

        ii)可执行:t.start();当你启动线程时,它会变成可执行的状态,意思是说它准备好要执行了,只要轮到它就可以开始,这时,该线程已经布置好执行空间。

        iii)执行中:所有的线程都在等待这一刻,成为执行中的那一个,这只能靠Java虚拟机的线程调度机制来决定,你有时也能对Java虚拟机选择执行线程给点意见,但无法强迫它把线程从可执行状态移动到执行中。

    (3)线程调度器在不同的Java虚拟机上面有不同的做法,就算同一个程序在同一台机器上运行也会有不同的遭遇。Java程序设计新手会犯的最糟错误就是只在单一的机器上测试多线程程序,并假设其他机器的调度器都有相同的行为。

    (4)Thread对象可以重复使用吗?能否调用start()指定新的任务给它?

        不行,一旦线程run()方法完成之后,该线程就不能再重新启动,事实上过了该点线程就会死亡,Thread对象可能还呆在堆上,如同活着的对象一般还能接受某些方法的调用,但已经永远地失去了线程的执行性,只剩下对象本身。

  16、集合与泛型

    (1)要使用TreeSet,下列其中一项必须为真

        集合中的元素必须是有实现Comparable的类型(得覆写compareTo(Object o)这个方法)

        使用重载、取用Comparator参数的构造函数来创建TreeSet(传入Comparator接口,覆写compare(Object one,Object two)这个方法)

    (2)数组的类型检查是在运行期间检查的,但集合的类型检查只会发生在编译期间。如果方法声明中参数为ArrayList<Animal>,它就只会取用ArrayList<Animal>,ArrayList<Dog>与ArrayList<Cat>都不行,因为假设你对Dog[]加入一个Cat(把Dog[]传入声明为Animal[]的参数中是完全合法的操作),编译是可以的,但运行的时候会报错。

    (3)在方法参数中使用万用字符时,编译器会阻止任何可能破坏引用参数所指集合的行为,你能够调用list中任何元素的方法,但不能加入元素,也就是说,你可以操作集合元素,但不能新增集合元素。如此才能保障执行期间的安全性,因为编译器会阻止执行期的恐怖行动。

   17、包、jar存档文件和部署

    无

  18、远程部署的RMI

    (1)RMI(Remote Method Invocation):远程程序调用

    (2)远程接口必须要extend过java.rmi.Remote这个接口,且所有的方法都必须声明RemoteException。

  附录B

    为什么要在乎String的不变性?

      当程序越来越大时,不可避免地会有很多String对象,为了安全性和节省空间(例如在手机上执行)的原因,String是不变的,意思是下面的代码

String s = “0”;
for(int x = 1; x < 10; x++){
    s = s + x;
}

      实际上会创建10个String对象(“0”,“01”,“012”.....“0123456789”)。最后会引用到“0123456789”这个值,但此时会存在10个String,创建新的String时,Java虚拟机会把它放到称为“String Pool”的特殊存储区中,如果已经出现同值的String,Java虚拟机不会重复建立String,只会引用已存在者。这是因为String是不变的,引用变量无法改变其它参考变量引用到的同一个String值。

 

Head First Java(第二版)——总结

原文:https://www.cnblogs.com/hlyxd/p/14759215.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!