Head First Java读书笔记
2023-03-24 08:48:57 0 举报
AI智能生成
登录查看完整内容
Head First Java 读书笔记
作者其他创作
大纲/内容
友好的语法、面向对象、内存管理、跨平台可移植性
优点
javac编译.java文件,生成.class文件(字节码)
启动Java虚拟机运行.class文件
工作方式
Java:Java1.02~Java1.1
Java2:Java1.2~Java1.4
Java5:Java1.5
Java版本
Java中integer和boolean两种类型不相容
重要知识点
每个Java程序至少一个类和一个main
1、基本概念
在堆中创建对象,可回收垃圾的堆。
变量加上public、static和final,变成全量变量
任何java中的事物都必须待在类中,pi常数和random()方法也必须定义在Math这个类中
把文件依据pkzip格式打包为.jar文件,通过manifest定义jar中哪一个文件带有启动应用程序的main方法
2、类和对象
32bits
float
64bits
double
一个小数,除非加上f,否则所有带小数的值都会被java当成double处理
浮点数
boolean
16bits
char
-128~127
8bits
byte
-32768~32767
short
int
long
数值
名称必须以字母、下划线或者doller符号开头,不能用数字开头
变量命名
对于primitive主数据类型的变量来说,变量值就是所代表的值,对于应用变量来说,变量值是取得特定对象的位标识法
声明一个引用变量
在堆上创建对象
连接对象和引用
对象的声明、创建和赋值
数组犹如杯架,一个个变量就是杯子,杯子放到杯架上,杯子里面可能直接装主数据,也可能装载的是对象的引用。数组自身也是一个对象,空间在堆中。
3、primitive主数据类型和引用
Java通过值传递,也就是拷贝传递
实例变量会有默认值,如果未初始化就会是默认值
局部变量没有默认值,如果在变量初始化前就使用的话,编译器会报错
变量默认值
int a = 3;byte b = 3;if (a == b)//true
比对两个变量的字节组合
判断两个引用是否引用同一个对象
==
变量的比较
4、方法操作实例变量
多次小规模发布
避免加入规格没有的功能
先写测试 用的程序
随时随地重构
保持简单
结对编程,并经常交换结对
极限编程(XP)
5、编写程序
要使用API的类,需要知道放在哪个包中
import可以省下每个类前面的包名称
java.lang是个预先被引入的包,可以不必须制定名称,java.lang.String和java.lang.System是对一无二的class,Java知道要去哪儿找
6、认识Java的API
子类会继承父类所有public类型的实例变量和方法,但不会继承父类所有private类型的变量和方法
继承下来的方法可以被覆盖掉,但实例变量不能被覆盖掉
运用多态时,引用类型是实际对象类型的父类,参数和返回值也可以多态
通过动态,引入新的子类型也不必修改程序
多态
存取控制,不标识为公有,非公有的类只能被同一个包的类作出子类
使用final修饰符
让类只拥有private的构造程序
如何阻止某个类被继承
如果只是想要防止特定方法被覆盖,可以将该方法标识上final修饰符
参数必须要一样,返回类型兼容
不能降低方法的存取权限
覆盖的规则
方法名称相同,但参数不同,重载和多态毫无关系
返回类型可以不同,不能只改变返回类型
可以更改存取权限
重载(overload)
7、继承和多态
设计为抽象类,在类声明前加上关键词sbstract
有些类不应该被初始化
抽象类
此方法一定要被覆盖
如果声明出一个抽象方法,必须将类标记为抽象类,不能在一个非抽象类中拥有抽象方法
抽象方法的意义在于无法实现方法的内容,但还是可以定义出一组子型共同的协议
抽象的方法没有内容,它只是为了标记出多态而存在
抽象方法
在Java中所有的类都是从Object这个类继承出来的
Object不是抽象类,它没有必须要被覆盖掉的方法
可以部分覆盖Object的方法,比如hashCode、equals、toString
Object通用对象、轻量化的对象,最常见的用途是用在线程的同步化
Java是类型检查很强的语言,如果某个对象用Object类型来引用,Java会把它当成Object类型的实例,只能调用Object类中声明的方法
任何从ArrayList<Object>取出的东西都会被当成Object类型的引用,而不管它原来是什么,需要将Object类型转换为原来类型,才能调用原有类型的方法
对象之母Object
使用接口可以解决多重继承的问题,Java不运行多重继承,因为那样会有致命方块的问题
Java的接口就好像是100%的纯抽象类
接口的方法一定是抽象的
如果想要定义出类可以扮演的角色,使用接口
接口
super.XXX()
子主题
调用父类的方法
8、接口和抽象类,深入多态
方法调用和局部变量在栈上
非primitive的变量,保存的是对象的引用,如果是具备变量,变量在栈上,对象在堆上。
实例变量存在于对象所属的堆空间上
栈与堆
如果没有构造函数,编译器会写一个
构造函数没有返回值,方法名和类名称相同。如果有返回值,那么就是方法,不是构造函数。
如果写了一个有参数的构造函数,并且需要一个没有参数的构造函数,那么必须自己动手写。编译器只有在完全没有构造函数的时候,才会自动生成一个构造函数。
构造函数可以以公有、私有或者不指定
在创建新的对象时,继承下来的构造函数都会执行,构造函数链
编译器会自动加上父类构造函数的调用supper(),编译器自动加的一定是没有参数的版本,假设父类有多个重载版本,也只有无参数的版本会被调用
有参数的父类构造函数需要显式调用
使用this可以调用同一个类的另外一个构造函数,this只能在构造函数的第一行,supper和this不能兼得
构造函数
不能对null引用使用圆点运算符,会抛异常
null
9、构造器和垃圾收集器
static关键字,不需要类实例的方法
静态方法不能调用非静态的变量
静态方法不能调用非静态的方法
可用使用引用变量替代类名称来调用静态方法,但是不推荐这样做
静态变量会在该类的任何对象创建之前或者该类的任何静态方法执行之前就会初始化
静态方法
静态的final变量是常数,在类加载之后静态final变量就一直会维持原值
在声明的时候直接初始化
static {XXX}
在静态初始化程序中
初始化
final的method代表不能覆盖掉此method
final的类代表不能继承该类
final
如果一个类只有静态方法,可以将构造函数标记为private以避免被初始化
在Java5.0之前,当需要用对象的方式处理primitive主数据类型时候,需要包装
Boolen
Character
Byte
Short
Integer
Long
Float
Double
包装类
调用类方法解开包装 int unWarpper = iWarp.intValue()
解开包装
generic类型的规则是只能指定类或者接口类型,ArrayList<int>将无法通过编译
不能直接声明ArrayList<int>
primitive主数据类的包装
Integer.parseInt(s)
Double.parseDouble(s)
String转换为primitive主数据
\"\" + d
使用 + 操作符,Java中唯一有重载过的操作符
Double.toString(d)
primitive主数据转换为String
类型转换
String.format(\
十进制整数,带逗号
小数点保留2位来格式化此浮点数
%.2f
整数部分以逗号形势标识,小数保留2位
数字的格式化
完整的日期和时间
%tc
只有时间
%tr
<用来告诉格式化程序重复利用之前的参数
%<tB %<td
Calendar.getInstance()
要取得当前的日期时间用Date,其他功能可以从Calendar上面找
日期格式化
import static java.lang.System.out out.println()
使用的时候可以少打个字,但是会带来名称冲突
静态import
10、数字与静态
如果有抛出异常,一定要用throw来声明这件事情
如果调用抛出异常的方法,需要用try/catch来处理异常
异常是Exception类型的对象
如果try或者catch块有return指令,finally还是会执行,流程会跳到finally然后再回到return指令
try/catch/finally
catch时,Java虚拟机只会从头往下找到第一个符合范围的异常处理块
catch时,异常需要从小排到大
方法可以抛出多个异常
可以不必明确声明每个可能抛出的异常,只声明父类就可以
catch块可以不对每个异常做处理,只要一个或者少数几个catch就可以处理所有的异常
异常多态
有申明会抛出异常,但是没有try/catch块,会duck掉异常留给调用方
不想处理异常时,duck掉异常
11、异常处理
12、图形用户接口
南北先占位高度,东西占位宽度,中间组件扣除周围剩下的
分割5个区域,每个区域1个组件
BorderLayout
流式布局,从左至右排列,有必要时换行
FlowLayout
就算水平宽度足以容纳组件,它还是会用新的行来排列组件
从上到下,每行1个
BoxLayout
三大管理器
13、swing
创建FileOutputStream
创建ObjectOutputStream
写入对象
关闭ObjectOutputStream
object -》ObjectOutputStream(对象被碾平)-》(连接到)FileOutputStream->文件
序列化对象写入文件
当对象被序列化时,被该对象引用的实例变量也会被序列化
implements Serializable
如果某个类是可序列化的,它的子类也自动地可以基序列化
如果某个实例变量不需要序列化,标识成transient(瞬时)变量
如果要让类能够被序列化,就实现Serializable
静态变量不会被序列化,因为静态变量每个类只有1个
序列化对象
创建FileInputStream
创建ObjiectInputStream
读取对象
转换为对象类型
关闭ObjectInputStream
如果对象在继承树上有个不可序列化的祖先类,那么就会执行类以及父类的构造函数
解序列化(Deserialization),还原对象
使用FileWriter替代FileOutputStream
将字符串写入文本文件
BufferedWriter writer = new BufferedWriter(new FileWriter(aFile));
缓冲区
File myfile = new File(\"MyText.txt\")
FileReader fileReader = new FileReader(myFile)
读取文本文件
String的split()可以把字符串拆开
查看某个类的ID:serialver Dog
static final long serialVersionUID = XXXXXXX
把ID拷贝到类上
Version ID,序列化的识别
14、序列化和文件的输入输出
java.net.Socket
Socket chatSocket = new Socket(\"196.164.1.103\
需要知道服务器的IP地址和端口号
16位宽,一个地址有65536个端口可以用,端口号范围0~65535
从0~1023的TCP端口保留给已知的特定服务使用
从1024~65535可是个人应用使用
不同的应用程序不能绑定同一个端口
TCP端口
建立socket连接
Client <- BufferedReader(缓冲区字符) <- InputStreamReader(转换为字符) <- Socket输入流(来自服务器的字节) <- Server
使用BufferedReader从Socket上读取数据
Client -> PrintWriter -> Socket输出(写上服务器的字节) -> Server
使用PrintWriter写数据到Socket上
服务器对特地端口创建ServerSocket
客户端对服务器应用建立Socket连接
Socket sock = serverSock.accejpt()
返回一个新的端口和客户端通信,ServerSocket空出来等待其它客户端的连接
服务器创建出与客户端通信的新Socket
服务器程序
建立Runnable对象
建立Thread对象,并赋值Runnable(任务)
执行runnable对象的run方法
启动Thread
启动新的线程
public class MyRunnable implements Runable{}
实现Runnable接口
调度器在不同的Java虚拟机上有不同的做法,同一个程序在同一个机器上运行也会有不同的遭遇
线程调度
使用synchronized关键字修饰方法,方法每次只能被单一的线程存取
每个Java对象都有一个锁,每个锁只有一把钥匙
锁不是在方法上,而是在对象上
同步化可能会导致死锁现象,原则上最好只做最小量的同步化,可以使用synchronized来修饰一行或数行的指令,而不必整个方法都同步化
只有有2个线程和2个对象,就可以引起死锁
假设Dog类有3个实例,那么有4个锁,3个实例的锁,还有一个类的锁,通过类的锁可以对静态对象同步化
静态对象也可以被同步化
线程的同步
线程
15、网络与线程
集合中对象必须实现Comparable类型
取用Com怕让投入参数的构造函数来创建TreeSet
有序状态保持并防止重复
TreeSet
可用成对的name/value来保存和取出
HashMap
针对经常插入或删除中间元素所设计的高效率集合
LinkedList
防止重复的集合,可快速找寻相符的元素
HashSet
类似HashMap,但可记住元素的插入的顺序,也可以设定成依照元素上次存取的先后来排序
LinkedHashMap
ArrayList不是唯一的集合
可以使用TreeSet或者Collections.sort来进行排序
泛型意味着更好的类型安全性,让问题在编译期就能发现,而不需要等到执行期才冒出来
仅Fish对象的引用能加入到ArrayList中,也能确保取出来的是Fish引用
ArrayList<Fish>
T可以是Animal或者animal的任何子类
等同如下语法:public void takeThing(ArrayList<? extends Animal> lsit)
public <T extends Animal> void takeThing(ArrayList<T> list)
只能是Animal
public void takeThing(ArrayList<Animal> list)
如上两种都合法,但是意义不同
运用泛型的方法
class Song implements Comparable<Song>
public int comparaTo(Song s)
Song实现Comparable,Song实现compareTo方法
class ArtisCompare implements Comparator<Song>{}
自定义比较器Comparator,在调用sort的时候传入比较器
两种方法
数组的类型在运行期间检查,但集合的类型检查只会发生在编译期间
可以操作元素,但是不能加入元素到集合中
万用字符?
泛型
LinkedHashSet
Set(interface)
ArrayList
Vector
List(interface)
Collection(interface)
Collection API
TreeMap
SortedMap(interface)
Hashtable
Map(interface)
大部分Java版本依据内存位置计算此序号
hashCode相等
equals方法返回true
对象相等
16、集合与泛型
本地部署
用户本地客户端,远程服务端
整个程序都在服务器端运行,客户端非Java,比如浏览器
部署的三种场景
编译时加上-d选项
源代码和类文件分离
确定所有的类文件都在classes目录下
创建manifest.txt来描述哪个类带有main()方法
执行jar工具来创建带有所有类以及manifest的JAR文件
把程序包进Jar
java -jar app1.jar
执行Jar
用包防止类名称冲突
反向使用domain的名称
com.headfirstjava(反向domain).project(包).Chart(类)
用domain防止包命名冲突
每个原始文件只有一个包指令
第一条语句,早于import语句
package
把类包进包中
javac -d ../classes com/headfirstjava/*.java
-d选项会自动创建目录
加上-d选项来编译
编译和执行包
确定所有的类文件都放在class目录下正确的相对应的包结构中
创建manifest.txt描述哪个类带有main,以及确认有使用完整的类名称
jar -cvmf manifest.txt packEx.jar com
只需要制定com目录就行
执行jar工具来创建带有目录结构与manifest的JAR文件
jar -tf packEx.jar
列出Jar内容
jar -xf packEx.jar
解开Jar包
用包创建Jar
如同浏览器plugin-in的小Java程序,管理下载、更新和启动JWS程序
客户端点击某个网页上JWS应用程序的链接(.jnlp文件)
web服务器收到请求发出.jnlp文件给客户端浏览器
浏览器启动Java Web Start,JWS的helper app读取.jnlp文件,然后向服务器请求MyApp.jar
Web服务器发送.jar文件
JWS取得JAR并调用指定的main()来启动应用程序,用户可以在离线的情况下通过JWS来启动应用程序
Java Web Start
17、发布程序(包、jar存档文件和部署)
远程程序调用Remote Method Invocation
RMI原生协议,为了Java对Java的远程调用而设计
JRMP
为了CORBA而产生(Common Object Requst Broker Architecture)
CORBA通常比RMI麻烦,若两端不全都是Java的话,就会发生一堆可拍的转译和交谈操作
IIOP
协议
客户端的辅助设施称为stub(桩)
服务器端的辅助设施称为skeleton(骨架)
JAVA RMI提供客户端和服务端的辅助设施对象
public interface MyRemote extends Remote{}
继承java.rmi.remote
public String sayHello() throws RemoteException;
生命所有的方法都会抛出RemoteException
创建Remote接口(MyRemote.java)
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote{}
实现Remote接口
继承UnicastRemoteObject
public MyRemoteImpl() throws RemoteException{}
编写无参数构造函数,并且抛出RemoteExpetion异常
向RMI Registry注册服务
实现Remote接口(MyRemoteImpl.java)
rmic MyRemoteImpl
MyRemoteImpl_Stub.class
MyRemoteImpl_Skel.class
产生两个helper对象
对实现类执行rmic
使用rmic产生stub和skeleton
rmiregistry
启动RMI Registry
java MyRemoteImpl
启动远程服务
创建远程服务
Naming.lookup(\"rmi://127.0.0.1/Remote Hello\")
客户端查询RMIRegistry
RMI Registry返回stub对象
客户端如何取得stub对象(MyRemoteClient)
MyRemote.class
MyRemoteImpl_stub.class
MyRemoteClient.class
Client
MyRemoteImpl.class
Server
客户端和服务端的类文件
放在HTTP WEB服务器上运行的Java程序
servlet
EJB服务器具有一组RMI以外的服务,比如交易管理、安全性、并发性、数据库和网络功能
EJB服务器作用于RMI调用和服务层之间
J2EE服务器包含了WEB服务器和EJB服务器(Enterprise JavaBeans)
EJB
查询服务使用IP组播技术为自己做宣传
服务向启动的查询服务注册
自适应探索(adaptive discovery)
服务注册时,返回租约,租约需要定期更新,否则服务就会被查询服务剔除
自恢复网络(self-healing newworks)
使用RMI,多了2个关键功能
Jini
18、分布式计算(远程部署的RMI)
Head First Java
0 条评论
回复 删除
下一页