《Thinking in Java》笔记

来源:互联网 发布:淘宝双11营销策略分析 编辑:程序博客网 时间:2024/05/17 07:09

第一章 对象导论

1.单根继承与泛型
java采用单根继承结构,终极的基类就是Object,所以所有都是都是Object类,所以当将对象引用到置入容器中时,那个对象就会被向上转型为Object类,取回时就得到一个对Object对象的引用,所以这时候就要向下转型,但是向下转型是不安全的,因为转完之后类型是不确定的(如向下转型可能是Circle或者Shape),所以java SE5增加了参数化类型,称为范型,为容器赋予了类型限制。如:
ArrayList shapes = new ArrayList();

Tips:
1.一个类所谓的接口其实就是方法,确定了对该对象能发送的请求(执行方法)。
2.java的垃圾回收机制会自动回收不再使用的对象。

第二章 一切都是对象

1.static关键字
当声明一个事物时static时,就意味着这个域或者方法不会与包含它的那个类的任何对象实例联系在一起。所以,即使从未创建对某个类的任何对象,也可以调用其static方法或访问其static域。

class Test(){    static int i = 7;}……//初始化两个对象,test1.i和test2.i都为7Test test1 = new Test();Test test2 = new Test();Test.i++;//执行之后test1.i和test2.i都为8

Tips:
1.Java中某个类的成员若是基本数据类型,即使没有初始化Java也会确保他有一个默认值。但若是“局部”变量,若在初始化时不指定值则变量可能得到的是任意值。
2.Java中任何传递对象的场合实际上传递的都是引用。若传递的是对象,则可以根据对象的内置方法修改对象的成员属性。

public class HelloWorld {    public static void main(String[] args) {        Obj ob = new Obj(1);        changeA(ob);        System.out.println(ob.a);    }    static public void changeA(Obj obj){        obj.setA(2);//改变a值        obj = new Obj(3);// obj指向新对象        obj.setA(4);//新对象改变a值,但不影响原来的对象,原对象的值还是a    }}class Obj{    int a;    public Obj(int a){        this.a = a;    }    public void setA(int a){        this.a = a;    }}最后输出值为2

第三章 操作符

1.赋值
对于基本类型,例如a=b,则则把b的值赋给了a,修改a,b的值不会受到影响。
对于对象,例如c=d,实际上是将“引用”从一个地方复制到另一个地方,那么c和d都指向同一个对象,修改任意一个数据两个都会受到影响。

Tips:
1.比较对象是,可以使用对所有对象使用的特殊方法equals(),但这个方法不适用于“基本类型”,基本类型使用==和!=比较。
2.布尔型不允许进行任何类型的转换处理,也不能对其进行任何运算。
3.Java中表达式出现的最大的数据类型决定了表达式最终结果的数据类型。

第四章 控制执行流程

1.for(类型 item :array){

}

第五章 初始化与清理

1.初始化顺序
在类的内部,即使变量的定义分散于方法定义间,仍旧会在任何方法(包括构造器)被调用之前得到初始化。

Calss Return(){    Return(int i){        Sysout.out.println(“Return+i);    }}Class Go(){    Return r1 = new Return(1);//初始化Go对象第一个执行    Go(){        Sysout.out.println(“Go”);//第三个执行    }    Return r2 = new Return(2);//第二个执行}Public Class Test(){    Public staic void main(String args[]){        Go go = new Go;    }}/*OutputReturn1Return2Go*/

2.数组

int[] a1 = {1,2,3};int[] a2;a2 = a1;//复制了一个引用而已此时修改a2,a1也会变化

第六章 访问控制权限

1.public、protected、包访问权限(默认访问权限)、private
访问权限由大到小:public、protected、包访问权限(默认访问权限)、private
public:对所有类可用
包访问权限:包中的所有其他类对该类有访问权限,对于包外的其他成员这个成员为private
protected:;作用与private相当,但是继承该成员的类可以访问该成员
private:只有包含该成员的类可以访问

2.例子
protected:

public class Cook(){    protected void doCook(){        …    }}

则对于所有继承Cook的类而言,即使不在同一包内,doCook都是可以使用的,若不是继承了Cook类,则就算同一包内也不能使用doCook(这点与private一样)。

private:

Class Water(){    private Water(){}    /*编写构造器覆盖默认的,又设置权限为private,使得在别的类中Water对象的创立只能用下面的函数了(Water w = Water.makeMater();)*/    public static Water makeWater(){        return new Water;//在类中故可以使用new Water();    }}

单例模式:

Class Water(){    private Water(){}    private static Water w = new Water();//与上面相比多了这一行    public static Water makeWater(){        return w;//返回的不再是new出来的对象,始终只能是w这个对象    }}

Tips:
1.(除了内部类)一个类的访问权限是能是public和包访问权限,不能是private和protected。
2.类定义在同一包内不同文件和同一文件对于权限的使用效果是一样的,而且一个文件内只能有一个public的类。

第七章 复用类

1.继承中,父类的方法不能是private的,这样的话子类如果不复写方法就无法使用。而数据成员一般权限为private。
2.在子类方法myPrint()中不能直接调用myPrint(),因为这样将会发生递归,但是Java可以用super.myPrint()来调用基类版本中的myPrint()函数。

class one{    public void myPrint(){        System.out.println(“one”);    }}public class Two extends one{    public static void main(String[] args) {        Two two = new Two();        two.myPrint();    }    public void myPrint(){        super.myPrint();        System.out.println(“two”);    }}/*Outputonetwo*/

3.Java会在子类的构造器中插入对基类构造器的调用。(继承并不只是复制基类的接口,在创建一个导出类的对象时,该对象包含了一个基类的子对象。)

class One{    One(){        System.out.println(“One”);    }}class Two extends One{    Two(){        System.out.println(“Two”);    }}class Three extends Two {    Three(){        System.out.println(“Three”);    }    public static void main(String[] args) {        Three three = new Three();    }}/*OutputOneTwoThree*/

4.@Override 复写(方法名称相同,参数的个数、类型相同,方法访问权限不能更严格)的注解,若使用该注解后你重载(方法名称相同,参数的个数或类型不同)了而不是复写,编译器会保错。
5.final关键字

final 含义:只能赋值一次的。
final 用法:
修饰属性,表示属性只能赋值一次,(1)基本类型:值不能被修改;(2)引用类型:引用不可以被修改该。
修饰方法,表示方法不可以重写,但是可以被子类访问(如果方法不是 private 类型话)。
修饰类,表示类不可以被继承。

static 含义:静态的,被 static 修饰的方法和属性只属于类不属于类的任何对象。
static 用法:
可以修饰内部类、方法和成员变量。
不可以修饰外部类、不可以修饰局部变量(因为 static 本身就是定义为类级别的,所以局部级别的变量是不可以用 static 修饰的)。

联合使用 static final
适用范围: 两者范围的交集,所以只能修饰:成员变量、方法、内部类。
修饰方法:属于类的方法且不可以被重写。
修饰成员变量:属于类的变量且只能赋值一次。
修饰内部类:属于外部类,且不能被继承

注意final修饰对象时,final使引用恒定不变,无法再指向另一个对象,但是能修改引用指向的对象。

public class Try{    public static void main(String[] args) {        final StringBuffer sb = new StringBuffer(“a”);        sb.append(“b”);//改变对象的内容        System.out.println(sb);    }}/*Outputab*/

还应该注意的一点是,使用final必须在域的定义处或者每个构造器中对final进行赋值。

public class GG(){    final int i = 1;//域的定义处    final int j;    GG(){        j = 2;//构造器中    }}

第八章 多态

  1. 多态的简单例子,假设Circle,Triangle都继承于Shape
void doSomething(Shape shape){    …    …}Circle circle = new Circle();Triangle triangle = new Triangle();doSomething(circle);doSomething(triangle);

2.下面代码我们希望输出的是“Two”,当父类One中p()方法的访问权限为private,被默认为final而不能被覆盖,所以Two中的p()相当于一个新的方法,与One中的p()方法无关联,只是名字一样而已,结论就是非private的方法才能被覆盖。

public class One{    private void p(){        System.out.println(“one”);    }    public staic void main(String args[]){        One x = new Two();        x.p();    }}class Two extends One{    public void p(){        System.out.println(“two”);    }}/*Outputone*/

第九章 接口

1.抽象类
抽象方法:仅有声明而没有方法体:abstract f();
抽象类:包含一个或多个抽象方法的类。
不能使用抽象类去创建对象,而如果一个类从抽象类继承并想创建一个对象,那么就必须为基类中所有的方法提供定义。如果不这样做,导出类(子类)便也是抽象类,编译器会强制我们用abstract关键字来限制这个类。

2.接口
interface这个关键字产生了一个完全抽象的类,它没有任何具体方法的实现,只提供方法名、参数列表和返回类型。在实现接口的类中,必须实现接口定义的所有函数。

interface one {    void one();}interface two {    void two();}class p{    void two(){}}class q extends p implements one,two{    @Override    public void one() {}}

上面的例子使用接口实继承现了多重,细心可以发现在q类中并没有实现two这个接口的two()方法,那是因为q继承了p,而p中已经有了two()这个方法,所以two()方法的定义随着继承而来了。

使用继承拓展接口

interface one {    void one();}interface two extends one{    void two();}class q implements two{    public one(){}    public two(){}}

Tips:
抽象类体现的是一种模板,它与子类是一种is-a的关系,而接口体现的是一种规范、约定、能力,它与实现类之间是一种like-a的关系。

第十章 内部类
作用:http://andy136566.iteye.com/blog/1061951/

第十一章 持有对象

Java容器类有两种类型,区别于容器中每个槽可以存放的元素个数。第一类只能放一个,List、Set、Queue,第二类放两个,Map。

1.List
List的一个典型的特性就是其长度是可变的,我们可以很方便地对它进行插入和删除元素的操作,这是它与数组所存在的一个很大的区别,后者的长度是固定的,而且我们不能从数组中删除元素,只能修改元素的值。利用Arrays.asList(array)将返回一个ArrayList,然而这个返回的ArrayList并不支持add和remove的操作,这里的ArrayList并不是java.util.ArrayList,而是Arrays的内部类。
ArrayList如果不指定类型则可以add()任何类型的数据,不过取出时要进行强制类型装换,因为存入时都被向上转换为Object类型。而如果指定类型(如ArrayList)则不需要强制装换了。
List转化为数组:toArray()方法
数组转化为List:Array.asList()方法
如果要进行大量的数据的访问就是用ArrayList,如果要经常进行删除和插入操作就使用LinkedList。而且利用LInkedLIst可以实现栈数据结构。

2.Set
HsahSet:获取元素最快
TreeSet:按照比较的结果存储数据
LinkedHashSet:按照被添加的顺序保存对象

3.Queue
offer():将元素插入队尾
peek()/element():不移除的情况下返回第一个元素,但是在队列为空时peek()返回null,而element()会报错
poll()/remove():移除并返回队头,队列为空时poll()返回null,remove()会报错
PriorityQueue(优先级队列)

4.Map
HsahMap:获取元素最快
TreeMap:按照比较的结果存储数据
LinkedHashMap:按照被添加的顺序保存对象

5.迭代器(Iterator)
只能单向移动,使用iterator()返回一个Iterator对象(Iterator it = list.iterator()),具有next()、hasNext()、remove()方法。
第一次使用next()得到第一个元素。

第十二章 通过异常处理错误

1.如果代码产生了异常:
a.处理这个异常

try{    //…}catvh(Eception e){    //..}finally{    //…}

b.在异常说明中表明这个方法将产生异常

void f() throws TooBig,TooSmall{    //…}

2.finally
什么时候使用finally:当要把内存(因为Java的垃圾回收机制,内存会自动释放)之外的资源恢复到它们的初始状态。

try{    //…    return;}finally{    print(“end”);}

即使return了,finally里面的语句依然会被执行。

3.异常匹配

try{    //…}catch(FatherException f){    //…}catch(SonException s){    //…}

如果把基类的catch子句放在前面,那么就会发现SonException的catch语句永远也得不到执行,因此会报错。

第十三章 字符串

1.String类中每一个看起来会修改String值得方法实际上都是创建了一个全新的String对象,而原来的对象没有改变。(upcase(String s)等)。
2.StringBuilder操作比过个String对象要更快。
3.String类常用方法。
4.正则表达式。

0 0
原创粉丝点击