Thinking in Java 笔记

Thinking in Java 笔记

1.oop:Object Oriented Programming 面向对象的程序设计

2.每个对象在内存中都有唯一的地址

3.类描述了具有相同特性(属性)和行为(方法)的对象集合

4.程序员的目的,创建(或者最好实在现有代码库(Github)中寻找)能够提供理想的服务来解决问题的一系列对象

5.如何分析一个对象:例如,加入你正在创建一个薄记系统,那么可以想象,系统应该具有某些包括了预定义的薄记输入屏幕的对象,一个执行薄记计算的对象集合,以及一个处理在不同的打印机上打印支票和开发票的对象。也许上述对象中的某些已经存在了,但是对于那些并不存在的对象,他们看起来像上面样子?他们能够提供那些服务?他们需要那些对象才能旅行他们的义务?

6.提高对象的高内聚性:例如,在检查打印模式的模块中,你可以这样设计对象,一个对象可以是所有可能的支票排版的目录,可以查询如何打印一张支票的信息;另一个对象可以是通用的打印接口,知道有关所有不同类型的打印机信息(可能是github有的接口了);第三个对象通过调用另外两个对象来完成打印任务。–就像这样,不仅允许通过购买获得对象那个,还可以创建能够在别处服用的新对象。

7.Java封装性的意义在于隐藏实现细节,隐藏的部分通常是程序内部脆弱的部分,很容易被粗心的不知情的程序员破坏,因此隐藏起来可以减少程序bug。

8.多态的好处:把一个对象不当做它所属的特定类型对待,而是当做是父类(基类),这样添加新的子类可以轻松拓展设计的能力,降低软件维护的代价。

9.对象(电视 new Tv())在堆上创建;对象的引用(遥控器 Tv tvController)在栈上创建;基本类型是直接将变量值存储在栈中

10.Java的容器(List,Map,Set):①不同容器提供了不同类型的接口和行为,某些容器提供的解决方案比其他容器灵活多了。②不同容器的某些操作有不同的效率。ArrayList和Linklist都是有相同的接口和外部行为的简单序列,但Arraylist随机访问元素是花费固定时间的操作,而Linklist随机取元素需要在列表移动,代价高,访问越尾的元素花费时间越长;而如果想在序列中间插入一个元素,Linklist开销比Arraylist小,因为Linklist只要改后一个元素的指定地址就能插入元素,而Arraylist要把插入位置后面的元素全部移项,花费高。我们可以一开始用Linklist构建程序,而在优化系统性能改用Arraylist。

11.泛型是为了解决向下转型(父类转子类)时转了错误的类型,而出现的运行时错误而设计的。

12.当一个对象存入容器的时候,他们会向上转型为Object类存入,但传出的时候,编译器是无法知道他传进来的时候是什么类型哦。(解决方法,加入泛型)

ArrayList<Shape> shapes = new ArrayList<Shape>();

13.对象的创建和生命周期(p13)–为什么选择Java?

14.必须由你创建所有对象(p22讨论 堆栈 堆 寄存器 等等概念)

15.BigInteger和BigDecimal用于处理高精度大数,牺牲速度换精度。

16.在花括号内定义的对象引用和对象,对象引用的作用于在花括号内,但对象会继续存在,需要通过垃圾回收期清理。

17.全局和静态的基本成员有初始值,局部变量可能是任意值,如果不赋值,有编译错。

18.Java参数的传递是值传递。

我们把对象传给方法里的形参,实际上我们相当于执行了copy()给新的引用,两个引用都指向了同一个地址,在方法中我们改变形参的值,实际上我们再次把形参指向新的地址,现在,这个地址发生的改变,不会影响到原来地址吧。如果你网上看到有人举了一个“引用传递”的例子,而且看起来“正确”,你可以从内存的角度,考虑一下为什么正确,正确了真的会影响到值传递这个事实吗?其实不然~

19.基本类型的初始值如int为0,boolean为false,而包装类型的初始值为null

20.有了基本类型为什么还要有包装类型呢?

我们知道Java是一个面相对象的编程语言,基本类型并不具有对象的性质,为了让基本类型也具有对象的特征,就出现了包装类型(如我们在使用集合类型Collection时就一定要使用包装类型而非基本类型),它相当于将基本类型“包装起来”,使得它具有了对象的性质,并且为其添加了属性和方法,丰富了基本类型的操作。

另外,当需要往ArrayList,HashMap中放东西时,像int,double这种基本类型是放不进去的,因为容器都是装object的,这是就需要这些基本类型的包装器类了。

21.静态方法其实与它的类无关。

22.static关键字,为了使被它修饰的事物,脱离于其任何对象实例存在,所以不需要创建对象就可以调用静态方法。

23."+"意味着''字符串连接'',如果必要,还有''字符串转换''

24.equals不适用与基本类型,因为是Object的方法,基本类型没有父类。

public void test4() {
        Integer a = new Integer(47);
        Integer b = new Integer(47);
        System.out.println(a == b);//地址不相等,false
        System.out.println(a.equals(b));//equals被重写了,值相等,true
    }

25.java不支持goto,但仍然是保留字。

26.父子初始化速度比较:父类静态代码块>子类静态代码块>父类构造方法>子类构造方法(构造器默认其实是静态方法)

27.区分重载:参数 顺序or数量or类型 的不同(顺序一般不用,会让代码难以维护)

28.返回当前对象的引用

Person walk(){
    return this;
}

28.垃圾回收器只会回收new分配的内存,而其他内存它不知道如何处理。java允许类中定义一个名为finalize()的方法,在垃圾回收准备释放对象占用的储存空间前,先调用finalize()方法,并在下次垃圾回收动作时,才真正回收对象占用的内存。

对象可能不被垃圾回收
垃圾回收并不等于"析构"("析构"是c++的概念)
垃圾回收至于内存有关

29.如果一直到程序执行结束,垃圾回收器都没有释放任何对象的储存空间,则随着程序的退出,那些资源也会全部交还给操作系统,因为垃圾回收本身也要开销,不使用,就不用支付这部分开销。

30.finalize()不是进行普通清理工作的合适场所

finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法。
finalize()与C++中的析构函数不是对应的。C++中的析构函数调用的时机是确定的(对象离开作用域或delete掉),但Java中的finalize的调用具有不确定性
不建议用finalize方法完成“非内存资源”的清理工作,但建议用于:① 清理本地对象(通过JNI创建的对象);② 作为确保某些非内存资源(如Socket、文件等)释放的一个补充:在finalize方法中显式调用其他资源释放方法。其原因可见下文[finalize的问题]

31.无论是"垃圾回收"还是"终结"都不保证一定发生,如果Java虚拟机并未面临内存耗尽的情形,他是不会浪费时间去执行垃圾回收以回复内存的。

32.静态数据初始化

public class StaticInitialization {
    /**
     * 
     * @Title: 静态数据的初始化   
     * @Description: TODO(复杂的跳转初始化)       
     * @return: 
     * 结论1:按顺序初始化 static 变量/对象 -> 执行主(static)方法 
     * 结论2:用构造函数new一个对象时 -> 先初始化改对象所在类的 static 变量/对象 -> 再执行构造(staitc)方法
     * 结论3:static 变量/对象 只会初始化一次(首次生成这个类的对象时,或者首次访问属于那个类的静态数据成员时)
     */
    public static void main(String[] args) {
        System.out.println("Create new Cupboard() in main");//11
        new Cupboard();//12
        System.out.println("Creating new Cupboard() in main");//16
        new Cupboard();//17
        table.f2(1);//21
        cupboard.f3(1);//22
    }
    static Table table = new Table();//0
    static Cupboard cupboard = new Cupboard();//5
}
class Bowl{
    Bowl(int marker) {
        System.out.println("Bow("+marker+")");
    }
    void f1(int marker) {
        System.out.println("f1("+marker+")");
    }
}
class Table{
    static Bowl bowl1 = new Bowl(1);//1
    Table(){
        System.out.println("Table()");//3
        bowl2.f1(1);//4
    }
    void f2(int marker) {
        System.out.println("f2("+marker+")");
    }
    static Bowl bowl2 = new Bowl(2);//2
}
class Cupboard{
    Bowl bowl3 = new Bowl(3);//8,13,18
    static Bowl bowl4 = new Bowl(4);//6
    Cupboard() {
        System.out.println("Cupboard");//9,14,19
        bowl4.f1(2);//10,15,20
    }
    void f3(int marker) {
        System.out.println("f3("+marker+")");
    }
    static Bowl bowl5 = new Bowl(5);//7
}

33.构造器的出现,保证了正确的初始化和清理,有了完全的控制,也就安全了。

34.package关键字的出现,是为了让编译器知道我们跟其他包的位置差异,这样public/protect/private才能限制访问权限。

35.package语句必须是文件中的第一行非注释程序代码。(不一定要在line1哦)

36.当编译器遇到import语句时,会在CLASSPATH里面找import后面的包名,然后从已编译的文件中找出名称相符者。

37.如果你import的两个包邮同名的class,这就存在潜在的冲突,但只要你不写那些导致冲突的程序代码,就没有问题。

//比如Vector.class冲突了,编译器不知道你new Vector是创建那个,就得下面这样写。
java.util,Vector v = new java.util.Vector();

38.private,默认,protected,public

//private:同类
//默认:同类,同包
//protected:同类/子类/同包,注意的是,不同包的子类去访问这样写:super.protected_Attr;(用super)
//public:同类,同包,不同包(所有..)

39.代理模式,可以隐藏真实者代理者选择性提供真实者的方法,避免真实者的所有方法暴露给使用者。

40.在继承里,子类的构造方法,默认第一行调用super(),除非你手动调用super(…)(父类其它构造方法),因为编译器肯定要你先初始化父类的,无论什么形式。如果你父类没有默认的构造方法,而是重写了带参数的构造方法,子类构造方法必须显式调用super(…),否则编译时错误。

41判断是否需要使用继承:问一下自己是否需要 从新类向基类进行向上转型(子类变父类),如果必须向上转型,则继承是必须的;但如果不需要,则好好考虑使用组合(依赖注入)还是使用继承

42.final修饰词

//一个永不改变的编译时变量(必须是基本类型,减轻运行时负担)
//一个在运行时被初始化的值,而你不希望它被改变
//对于基本类型,final使数值恒定不变;而使用对象引用,final使引用恒定不变。(一旦引用被初始化执向一个对象,就无法再把它指向另一个对象。然而对象自身是可以被修改的,java并未提供使任何对象恒定不变的途径;数组,字符串都是对象!!)
//貌似,使引用成为final,没有使常量成为final用处大

43.定义为static,强调只有一份,定义为final,强调是常量。

44.空白final(final修饰的变量使用前必须初始化,空白final让初始化延迟且更加灵活,可以根据对象而有所不同)

class Test2 extends Day3{ 

    private final String name;

    public Test2(String name) {
        super(name);
        this.name = name;
    }

    public static void main(String[] args) {
        Test2 tt= new Test2("suguowen");
        System.out.println(tt.name);
        //tt.test1();
    }
    public void test1() {
        Day3 d = new Day3();
        /*System.out.println(super.private_Num);
        System.out.println(super.default_Num);*/
        System.out.println(super.protected_Num);
        System.out.println(super.public_Num);
    }
}

45.

猜你喜欢

转载自www.cnblogs.com/suguowen/p/9130432.html