美文网首页
Thinking In Java 读书笔记

Thinking In Java 读书笔记

作者: geverway | 来源:发表于2016-02-23 19:29 被阅读1451次

    ==========================

    create by wythe             2016/2/15 21:49
    

    在看TIJ之前,已经有了C/C++的一点基础。最近因为参加学校的软件编程比赛,做移动端的app,马马虎虎算是弄完了。在做得过程发现自己的java不熟悉(菜的一笔),所以闲时就看看这本经典,做些笔记

    一 、 Introduction to Object
    • 主数据类型(Primitive Type)
    类型 大小 默认值
    byte 8 bits (byte)0
    char 16 bits '\u0000'(null)
    boolean 1 bit false
    short 16 bits (short)0
    int 32 bits 0
    long 64 bits 0L
    float 64 bits 0.0f
    double 64 bits 0.0d

    若主数据类型属于一个类成员,则会以上述的默认值初始化。但是局部变量会得到随机值
    99

    二 、 Everything is Object
    • String str = new String("hello world") str为句柄

      Java通过句柄(str)来操作对象;
      句柄(str)在它的作用域(Scope)终点自动销毁,然而句柄指向的对象还占据内存空间;

    • 内存
    类型 作用
    寄存器(Registers) 我们没有直接控制权,只能由编译器分配
    堆栈(The stack) 对象句柄的储存的地方
    堆(The heap) 对象的储存地方
    • 注意点

    如果您的main()用package语句封装到一个文件里,那么必须在程序名前面指定完整的包裹名称,否则不能运行程序。

    三 、 Operator
    • ==和!=运算符

    关系运算符==和!=也适用于所有对象。下面是一个例子:

    //:
    Equivalence.java public class Equivalence { 
         public static void main(String[] args) {     
                  Integer n1 = new Integer(47);    
                  Integer n2 = new Integer(47);     
                  System.out.println(n1 == n2);     
                  System.out.println(n1 != n2);  
         }
    } ///:~ 
    

    其中,表达式System.out.println(n1 == n2)
    可打印出内部的布尔比较结果。一般人都会认为输出结果肯定先是true,再是false,因为两个Integer对象都是相同的。但尽管对象的内容相同,句柄却是不同的,而==和!=比较的正好就是对象句柄。所以输出结果实际上先是false,再是true。这自然会使第一次接触的人感到惊奇。 若想对比两个对象的实际内容是否相同,又该如何操作呢?此时,必须使用所有对象都适用的特殊方法equals()。但这个方法不适用于“主类型”,那些类型直接使用==和!=即可。由于equals()的默认行为是比较句柄。所以除非在自己的新类中改变了equals(),否则不可能表现出我们希望的行为

    • 移位运算符

    1、左移位运算符(<<)能将运算符左边的运算对象向左移动运算符右侧指定的位数
    (在低位补0);
    2、“有符号”右移位运算符(>>)则将运算符左边的运算对象向右移动运算符右侧指定
    的位数。“有符号”右移位运算符使用了“符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1;
    3、Java也添加了一种“无符号”右移位运算符(>>>),它使用了“零扩展”:无论正负,都在高位插入0;

    • 主数据类型(int、long etc.)的二进制为补码形式,用以下代码验证
    //:Main.java
    //Test for Learning Java
    package com.company;
    import java.util.*;
    public class Main {
        public static void main(String[] args) {
        // write your code here
            int i = -1;
            printIntBinary(i);
            printIntBinary(i>>3);
            printIntBinary(i>>>3);
        }
        static void printIntBinary(int a){
            for(int j = 31; j >= 0; --j) {
                if((( 1 << j ) & a ) != 0)
                    System.out.print("1");
                else
                    System.out.print("0");
            }
            System.out.println();
        }
    }
    ///:The end~
    

    结果:


    结果
    • javadoc sample.class

    通过代码的注释,自动生成api文档 教程

    四 、 Initialization & Clean up
    • 对象初始化

    static变量在非static变量前初始化
    示例:

    class Man{
        static int cnt;
        String name;
        //static区块用于初始化static变量
        static{
            cnt=1;
        }
        //非静态变量的初始化区块,支持"匿名内部类"的初始化
        {
            name = "Mike";
        }
        Man(){
            cnt++;
        }
    }
    
    • 数组初始化

    1、主数据类型(int、char etc.):表达式int[] a = new int[size]产生长度为sizeint数组,初始化值为默认值0.
    2、对象:表达式Interger[] a = new Interger[size]产生一个句柄数组,具体的对象空间未分配。此时,数组元素的值为null。通过a[i] = new Interger(2)来关联对象.

    • 多维数组

    多维数组可以任意指定各维的大小
    示例:

    int [][][] a = new int[randInt()][][];
    for(int i = 0; i < a.length; ++i){
         a[i] = new int[randInt()][];
         for(int j = 0; j < a[i].length; ++j){
              a[i][j] = new int[randInt()];
              for(int k = 0; k < a[i][j].length; ++k)
                    a[i][j][k] = i*j*k;
          }
    }
    
    • finalize()方法

    Java提供了一个名为finalize()的方法,我们可以在自己类中定义它。它的工作原理:当垃圾收集器准备好释放对象占用的储存空间,它会首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象内存。因此,可以用finalize()在垃圾收集期间进行一些重要的清除工作
    示例:

    //: initialization/TerminationCondition.java 
    // Using finalize() to detect an object that 
    // hasn’t been properly cleaned up.  
    class Book {
        boolean checkedOut = false;
        Book(boolean checkOut) {
            checkedOut = checkOut;
        }
        void checkIn() {
            checkedOut = false;
        }
        protected void finalize() {
            if(checkedOut)
                System.out.println("Error: checked out");
    // Normally, you’ll also do this:     
    // super.finalize(); 
    // Call the base-class version   
        }
    }
    public class TerminationCondition {
        public static void main(String[] args) {
            Book novel = new Book(true);
    // Proper cleanup:  
            novel.checkIn();
    // Drop the reference, forget to clean up:     
            new Book(true);
            // Force garbage collection & finalization:    
            System.gc();
        }
    }
     /* Output: Error: checked out *///:~
    
    五 、Access Control
    • 修饰符

    1、friendly默认的访问修饰符,它不是显式的,不用特意来使用它。它指明可在包内访问,包外不可访问。
    2、protected在包内访问上与friendly一致。但protected可访问性比friendly强。

    可看以下图片,红色为语法错误


    Package1
    Package2
    六 、Reusing Classes
    • final关键字

    1、自变量final:例如,
    void sampleMethod(final sampleClass s)中,无法改变自变量s句柄的指向(对象);
    2、空白final:例如,

    class blankFinal{
            final int i; 
            blankFinal(){
                i = 1;
            }
    }
    

    在对象初始化时,对final进行正确的赋值;

    七、 Polymorphism
    • 多形性实例

    //:Main.java
    //Test for Learning Java
    package com.company;
    import com.company.tools.*;
    class Instrument{
    public void play(){
    CustomPrint.print("Instrument~");
    }
    }
    class Wind extends Instrument{
    public void play(){
    CustomPrint.print("Wind~");
    }
    }
    class Brass extends Instrument{
    public void play(){
    CustomPrint.print("Brass~");
    }
    }
    class Brass2 extends Brass{
    public void play(){
    CustomPrint.print("Brass2~");
    }
    }
    public class Main {
    public static void tune(Instrument isn){
    isn.play();
    }
    public static void main(String[] args) {
    Brass brass = new Brass();
    Brass2 brass2 = new Brass2();
    tune(brass);
    tune(brass2);
    }
    }
    ///:The end~

    ![结果](https://img.haomeiwen.com/i1623908/565bb364a569d2df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    如果,
    将上述的`play()`方法,加上static关键字`public static void play()`,则结果是:
    ![结果](https://img.haomeiwen.com/i1623908/76d9edf55c437f8d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    - 接口
    >***1、接口介绍***
    1)接口不规定方法主体;
    2)接口可以声明**基本数据类型**的数据成员,它们都***默认***为static 和final;
    3)与类相似,我们可在interface关键字的前面添加一个 public关键字(但只有接口定义于同名的一个文件内);或者将其省略,营造一种“friendly”状态;
    4)接口中的方法声明默认为 public。所以在实现一个接口的时候,来自接口的方法***必须***定义成public。不然它们会默认为“friendly"
    就像这样,
    

    interface Instrument5 {
    // Compile-time constant:
    int i = 5; // static & final
    // Cannot have method definitions:
    void play(); // Automatically public
    String what();
    void adjust();
    }

    接口也具有多形性。下面这段代码的结果和`多形性实例`的结果一致:
    

    //:Main.java
    //Test for Learning Java
    package com.company;
    import com.company.tools.*;
    interface Instrument{
    void play();
    }
    class Wind implements Instrument {
    public void play(){
    CustomPrint.print("Wind~");
    }
    }
    class Brass implements Instrument {
    public void play(){
    CustomPrint.print("Brass~");
    }
    }
    class Brass2 extends Brass{
    public void play(){
    CustomPrint.print("Brass2~");
    }
    }
    public class Main {
    public static void tune(Instrument isn){
    isn.play();
    }
    public static void main(String[] args) {
    Brass brass = new Brass();
    Brass2 brass2 = new Brass2();
    tune(brass);
    tune(brass2);
    }
    }
    ///:The end~

    **2、接口实现“多重继承”**
    >就像这样,`class samlpe implements interface1,interface2,interface3`。sample可以将类型上溯至interface1,interface2,interface3中的任意一种。下面是一个实例:
    

    //: Adventure.java
    // Multiple interfaces import java.util.*;
    interface CanFight { void fight(); }
    interface CanSwim { void swim(); }
    interface CanFly { void fly(); }
    class ActionCharacter { public void fight() {} }
    class Hero extends ActionCharacter
    implements CanFight, CanSwim, CanFly {
    public void swim() {}
    public void fly() {}
    }
    class Adventure {
    static void t(CanFight x) {
    x.fight();
    }
    static void u(CanSwim x) {
    x.swim();
    }
    static void v(CanFly x) {
    x.fly();
    }
    static void w(ActionCharacter x) {
    x.fight();
    }
    public static void main(String[] args) {
    Hero i = new Hero();
    t(i); // Treat it as a CanFight
    t(i); // Treat it as a CanSwim
    v(i); // Treat it as a CanFly
    w(i); // Treat it as an ActionCharacter
    }
    } ///:~

    **3、接口能够继承接口**
    >像这样`interface sample extends interface1,interface2,interface3`,形成更丰富的新接口
    **4、接口产生枚举数组**
    >就像这样,
    

    public interface Months{
    int
    JANUARY = 1, FEBRUARY = 2, MARCH = 3,
    APRIL = 4, MAY = 5, JUNE = 6, JULY = 7,
    AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10,
    NOVEMBER = 11, DESEMBER = 12;
    }

    接口内的基本数据类型默认为***final*** **&** ***static***,可以***Months.JANUARY***的方式访问。
    
    - 内部类
    >**1、内部类,一个被定义在现有类内部的新类。**
    像这样,
    

    public class Parcel1 {
    class Contents {
    private int i = 11;
    public int value() { return i; }
    }
    class Destination {
    private String label;
    Destination(String whereTo) {
    label = whereTo;
    }
    String readLabel() { return label; }
    }
    public Contents cont(){
    return new Contens();
    }
    public Destination to(){
    return new Destination();
    }
    // Using inner classes looks just like
    // using any other class, within Parcel1:
    public void ship(String dest) {
    Contents c = new Contents();
    Destination d = new Destination(dest);
    }
    public void ship2(String dest){
    Contents c = cont();
    Destination d = to(dest);
    }
    public static void main(String[] args) {
    Parcel1 p = new Parcel1();
    p.ship("Tanzania");
    Parcel.Contents c = p.cont();
    }
    }

    **2、可在方法或者if语句等的作用域内内嵌一个内部类,但是这个内部类仅限在这个作用域内使用**
    **3、匿名类,方法尾部return一个内部类**
    像这样,
    

    public Content cont(){
    return new Content(){
    private int i = 0;
    public int value(){return i;};
    }
    }

    new 表达式返回的句柄会自动上溯到Content,由此,可以重写Content的方法来隐藏实现细节1-·
    **4、当一个新类继承一个外部类时,外部类内嵌的内部类不会被自动继承。因此,无法再新类中简单地覆盖内部类**
    实例:
    

    //: BigEgg.java
    // An inner class cannot be overriden
    // like a method
    class Egg {
    protected class Yolk {
    public Yolk() {
    System.out.println("Egg.Yolk()");
    }
    }
    private Yolk y;
    public Egg() {
    System.out.println("New Egg()");
    y = new Yolk();
    }
    }
    public class BigEgg extends Egg {
    public class Yolk {
    public Yolk() {
    System.out.println("BigEgg.Yolk()");
    }
    }
    public static void main(String[] args) {
    new BigEgg();
    }
    } ///:~

    输出:New Egg( )
              Egg.Yolk( )
    **5、可以用“外部类.内部类”的方式来继承内部类,并可用这种方法来覆盖父类内部类的方法**
    下面是例子:
    

    //: BigEgg2.java
    // Proper inheritance of an inner class
    class Egg2 {
    protected class Yolk {
    public Yolk() {
    System.out.println("Egg2.Yolk()");
    }
    public void f() {
    System.out.println("Egg2.Yolk.f()");
    }
    }
    private Yolk y = new Yolk();
    public Egg2() {
    System.out.println("New Egg2()");
    }
    public void insertYolk(Yolk yy) { y = yy; }
    public void g() { y.f(); }
    }
    public class BigEgg2 extends Egg2 {
    public class Yolk extends Egg2.Yolk {
    public Yolk() {
    System.out.println("BigEgg2.Yolk()");
    }
    public void f() {
    System.out.println("BigEgg2.Yolk.f()");
    }
    }
    public BigEgg2() { insertYolk(new Yolk()); }
    public static void main(String[] args) {
    Egg2 e2 = new BigEgg2();
    e2.g();
    }
    } ///:~

    输出:   Egg2.Yolk()
              New Egg2()
              Egg2.Yolk()
              BigEgg2.Yolk()
              BigEgg2.Yolk.f()
    
    #####八、Honding Your Objects
    - continue配合标签使用,可以连跳多级循环
    >```
    retry:
        while(true){
            int t=
                    (int)(Math.random()*flav.length);
            for(int j=0;j<i;j++)
                if(picks[j]==t)continue retry;
        }
    
    • 命令行下编译运行sample.java
      //cd 到com文件夹的上一级(如果是在IED(IJ)中生成的)

    javac sample.java
    //文件不含包名
    java sample
    //如果文件包含“package com.package”,则
    java com.package.sample

    还需要注意,“CLASSPATH=.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar”。其中,".;"表示当前路径

    九、Strings
    • StringBuilder
    • 正则表达式

    String mp = "\w+@(\w+\.)+[A-Za-z]{2,14}";
    String mail = "vicent@fzu.edu.cn";
    Pattern p = Pattern.compile(mp);
    Matcher m = p.matcher(mail);

    十、 Runtime Type Indente

    相关文章

      网友评论

          本文标题:Thinking In Java 读书笔记

          本文链接:https://www.haomeiwen.com/subject/rsabkttx.html