Head First JAVA 读书笔记


JAVA程序执行过程:源代码(.java) 经过编译形成字节码组成的 .class文件,启动JAVA虚拟机(JVM)来运行.class文件。JVM会将字节码转换成平台所能理解的形式来运行,所以JAVA是平台无关的。

JAVA中所有东西都会属于某个类,源文件.JAVA会被编译为类文件.class,真正被执行的是类文件。main()函数是程序的起点。

JAVA的对象存放在堆中,这个堆叫可回收垃圾的堆(Garbage-Collectible Heap),JVM会替开发人员管理内存,当JVM察觉到某个对象不再被使用时,会将它回收掉,以释放内存。

JAVA中有两类数据类型:primitive主数据类型和引用

primitive主数据类型包括
boolean (长度由JAVA虚拟机决定)
char 16bits
byte 8bits
short 16bits
int 32bits
long 64bits
float 32bits
double 64bits
带有小数点的数字都会被编译器认为是double类型的,如果在该数字后面加上 f 就可以让编译器认为是float类型的数字。

JAVA变量必须以_或字母或$为开头,不能使用保留字。

Dog d = new Dog();
d不能称之为变量,而应该称为引用。这个引用实际上是地址,类型指向对象的指针。
真正产生对象的是new Dog()这一句,会在堆上分配空间建立Dog对象。上面一整句有两个步骤:创建对象,连接对象和引用。

Book a = new Book();
Book b = new Book();
这里一共创建了两个对象,并且有两个引用分别指向它们各自的对象。
Book c = a;
这里没有创建对象,而新声明了引用。这样引用c和引用b指向同一个对象。
b = a;
这里引用b指向了引用a的对象,那引用b之前指向的对象不再被引用,JVM将会对其进行回收。

数组是一个对象。

封装
将数据隐藏起来有益于保密,即将实例变量声明为private,而通过public的getter方法和setter方法控制存取实例变量。
十一
实例变量是声明在类中的,局部变量是声明在方法中的。
十二
即使是没有明确地赋值给实例变量,实例变量仍然会有值,是默认值。数字的primitive类型为0,boolean类型为false,对象引用为null。
十三
局部变量在使用前必须初始化,因为它没有默认值。方法的参数基本上与局部变量是相同的。
十四
用==来比较primitive主数据类型是否相等,==也可以用来比较两个引用是否引用堆上的同一个对象。如果要比较两个对象是否相等,用equals()。
十五
for循环的两种方式

for(int i=0;i<100;i++){}
for(string name:nameArraty){}

十六
ArrayList是JAVA函数库中一个集合类,有一下方法

add(Obeject elem)//添加新元素
remove(int index)//删除特定位置的元素
remove(Object elem)//删除指定元素
contains(Object elem)//查询特定元素
isEmpty()//检查是否为空
indexOf(Object elem)//查询特定元素的位置
get(int index)//获取特定位置的元素
size()//获取集合的元素数量,数组可以用length()

十七
数组和ArrayList的区别
数组在创建的时候必须确定大小,ArrayList不用;数组存放元素元素时必须知道位置,ArrayList不用。ArrayList的大小是可调整的,数组不是。
十八
在多级继承的时候,要调用对象的方法,会调用继承树中与对象最接近的方法。
十九
在JAVA中,子类要调用父类的方法可以用super关键字,如:

super.roam();//调用父类的roam()方法

如果要调用父类的无参构造函数,super();必须是子类无参构造函数的第一句。
二十
一般引用类型是和引用的对象类型是一样的,但是多态可以让引用类型为Animal,而对象类型为Dog。就是说,运用多态时,引用类型可以是对象类型的父类。多态的好处比如说使用Animal类型作为参数,那么传进来的参数可以是Dog或者Cat,而不需要为Dog和Cat分别写两个方法。
二十一
三种方法防止类生成子类。
1.存取控制。类不可以被标记为私有的,但是可以被标记为非公有的,非公有的类只能被同一个包的其他类作出子类。
2.使用final修饰符,表示此类不能被继承。
3.让这个类只拥有private的构造函数。
二十二
final修饰方法的时候表示方法不能被覆盖
二十三
覆盖(又叫重写)(override)的时候方法要同名,参数必须要一样且返回类型必须要兼容,并且不可以降低方法的存取权限。
二十四
重载(overload)是指方法的名称相同,但参数不同,与返回类型无关。重载和多态毫无关系。
二十五
抽象类不可以被初始化。
二十六
抽象类必须被继承,抽象方法必须被重写(可以不必要在继承树下一层重写而在下下层重写)。抽象方法没有方法体。如果类中声明了抽象方法,那么类必须标记为抽象类。
二十七
Object类是JAVA中所有类的父类,基本方法有:

equals(Object o)//判断两个对象是否真正相等
getClass()//获取对象的类型
hashCode()//列出对象的哈希码
toString()//

二十八
使用Object类型的多态引用带来的问题
ArrayList 类型允许添加Dog类型对象。比如

ArrayList<Dog> myDogs = new ArrayList<Dog>();
Dog myDog = new Dog();
myDogs.add(myDog);

多态允许将父类引用指向子类对象,但是不允许将子类引用指向父类对象,比如

Dog newDog = myDogs.get(0);//不能通过编译

只能 . 出来引用类型所具有的属性和方法,而不是对象类型所具有的属性和方法。比如

Animal ani = new Dog();
ani.animalBark();//Animal类型的animalBark()方法,可以调用
ani.dogRun();//Dog类型的dogRun()方法,不能调用

在将父类引用指向子类对象这种情况,这个父类引用只能调用父类类型有的属性和方法。属性不存在重写,如果子类对象没有重写该父类方法,则调用父类的方法,如果子类重写了父类的方法,则调用子类的方法。
二十九
JAVA真的不支持多重继承,因为会引起致命方块的问题,即当
CDBurner类继承了DigitalRecorder类,并且重写了burn()方法,DVDBurner类同样继承了DigitalRecorder类,并且重写了burn()方法。而ComboDriver类型继承了CDBurner类和DVDBurner()类,当ComboDriver对象调用burn()方法时,不知道到底调用哪个父类的burn()方法。
三十
接口可以解决多重继承的问题。只要全部方法都是抽象的,父类没有实现,子类必须实现这些抽象方法,这样JVM就不会犹豫执行哪个版本的父类方法了。
三十一
接口就好像是100%的纯抽象类,继承多个接口用implements关键词。 抽象类可以带有抽象方法和非抽象方法。
三十二
方法调用和局部变量是存放在栈中的,而对象和实例变量是存在堆上的。栈顶的方法是目前正在执行的方法。对象引用如果是局部变量,那将存放在栈上,如果是实例变量,则保存在对象中,也即堆上。
三十三
构造函数不是方法,构造函数不声明返回类型,且函数名与类名同名。构造函数是在创建对象的时候执行的代码。一般使用构造函数来初始化状态。如果声明了有参构造函数,最好还要声明无参构造函数,不声明其实也可以。只要自己编写了一个构造函数,编译器就不会自动生成构造函数;如果没有编写构造函数,编译器会生成默认构造函数。构造函数可以重载。构造函数不一定是公有的。
三十四
实例变量有默认值,各原始的默认值分别有0/0.0/false/null。局部变量没有默认值
三十五
this和super只能用在构造函数中,且必须是构造函数中第一行,同一个构造函数不能同时出现this和super调用。this表示当前对象的引用,super表示父类的引用。
三十六
实例变量的声明周期和对象的生命周期相同。只要有或者的引用,其对象也会活着。如果对象唯一的引用死了,那对象将会被GC从堆中清除,但什么时候去清除不知道。也就是说,当最后一个引用消失时,对象就变成可回收的。
三十七
三种方法释放对象的引用
1.引用离开作用域;
2.引用指向其他对象;
3.将引用设置为null;
三十八
在创建新对象时,所有继承下来的构造函数都会执行,而且父类构造函数必须在子类构造函数执行之前执行。抽象类也有构造函数。
三十九
null代表的是空字节组合,实际上是什么只有JVM知道。
四十
静态类表示不需要实例变量的一种类,它不能创建对象。静态方法表示不需要实例变量的一种方法。
四十一
可以用私有的构造函数防止类被初始化,因为私有方法只能在类内部调用。
四十二
静态方法不能调用类中非静态的成员。静态变量被所有类的实例所共享。如Dog类声明有诸多对象,但静态的host实例变量只有一个。所以,实例变量是每个实例一个,静态变量是每个类一个。
四十三
静态变量是在类被加载时所初始化的,类会被加载通常是因为创建类的对象或者调用类的静态变量或方法。但是静态变量的初始化有两项保证:
1.静态变量会在该类的任何静态方法加载前被初始化;
2.静态变量会在该类的任何对象被创建前被初始化。
四十三
主数据类型的静态变量会被设定默认值。
四十四
静态的final变量是常数,所以不会被设定默认值。静态的final变量的两种初始化方法:
1.

public class Foo{
	public static final int FOO_X=25;
}
public class Foo{
	public static final int FOO_Y;
	static {//这个方法会在类加载时被执行,这是个匿名的静态方法
		FOO_Y=(int)Math.random();
	}
}

四十五
final的变量表示不能改变它的值
final的method表示不能被覆盖
final的class表示不能被继承
四十六
非静态方法可以调用静态变量
四十六
Math的静态方法
1.Math。random() 返回 [0.0)之间的double类型的数字
2.Math.abs(x) 按x的类型返回x的绝对值
3.Math.round(x) 四舍五入返回int类型或者long类型的数字
4.Math.min(x,y) 按x或y的类型返回较小的一个数字
5.Math.max(x,y) 按x或y的类型返回较大的一个数字
四十七
primitive主数据类型的包装类型可以创建对象,他们是Boolean,Character,Byte,Short,Integer,
Long,Float,Double
包装primitive类型

Integer iWarp = new Integer(i);

解开包装

int unWrapped = iWarp.intValue();

在JAVA 5.0之前想要以对象的方式处理主数据类型时必须要手动包装,而之后的版本不在需要,因为有autoboxing。
四十八
数字的格式化
四十九
日期格式化
五十
将String类型转换成primitive主数据类型

String s = "2";
int x = Integer.parseInt(s);
double y = Double.parseDouble("123.22");
boolean z =new Boolean("true").booleanValue();

将primitive主数据类型值转换成String类型

double d =4.21;
String doubleString = ""+d;//+号是唯一被JAVA重载过的运算符,这里字符串+数字将这样运算:字符串拼接上数字的字符串
String doubleString = Double.toString(d);

五十一
Java的异常处理机制的try/catch块的流程控制
1.如果try/catch代码块没有发生异常,那try/catch块只执行try里面的语句,然后执行try/catch块后面的语句,而不执行catch里面的语句;
2.如果try/catch代码块发生的异常,那try里面只会执行到异常语句,然后直接跳到catch,执行catch里面的语句,接着执行try/catch块里面的语句
3.如果try/catch块还有finally部分,那不管有没有发生异常,那都会按顺序执行到finally部分
4如果try/catch里面有return语句,那代码会在执行return之前先执行finally里面的语句最后回到return语句。
五十二
可以由一个方法抛出异常,而另一个方法捕捉住异常

//可能抛出异常的方法
public void takeRisk() throw BadException{
	if(abandonAllHope){
		throw new BadException();//创建Exception对象并抛出
	}
}
//调用该方法的方法捕捉该异常并处理
public void crossFingers(){
	try{
		obj.takeRisk();
	}catch(BadException ex){
		ex.printStackTrace();//列出有用的异常信息 
	}
}

五十三
将序列化对象写入文件

//创建对象
FileOutputStream fs = new FileOutputStream("MyGames.txt");
ObjectOutputStream os = new ObjectOutputStream(fs);
//写入对象
os.writeObject(characterOne);
os.writeObject(characterTwo);

Java中数据是在串流(stream)中移动的,一般来说,串流是两两连接才能起作用。比如,FileOutputStream将字节写入文件,而ObjectOutputStream将对象序列化成可以写入串流的数据。
当对象被序列化时,被该对象引用的实例变量会被序列化,且所有被引用的对象也会被序列化。
五十四
要使得类能够被序列化,就要实现Serializable接口。

import java.io.*;//使用Serializable接口必须import的
public class Box implements Serializable{//不需要实现方法,只需要实现接口

}

五十五
使用解序列化(Deserialization)还原对象

//创建对象
//这个串流用于连接文件
FileInputStream fileStream = new FileInputStream("MyGame.ser");
//这个串流用来读取对象
ObjectInputStream os = new ObjectInputStream(fileStream);
//转换类型
GameCharacter elf = (GameCharacter )one ;
//关闭串流
os.close();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值