Thinking In Java 读书笔记

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

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~

![结果](http://upload-images.jianshu.io/upload_images/1623908-565bb364a569d2df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
如果,
将上述的`play()`方法,加上static关键字`public static void play()`,则结果是:
![结果](http://upload-images.jianshu.io/upload_images/1623908-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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,577评论 18 399
  • 多态 任何域的访问操作都将有编译器解析,如果某个方法是静态的,它的行为就不具有多态性 java默认对象的销毁顺序与...
    yueyue_projects阅读 933评论 0 1
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,597评论 18 139
  • 【程序1】 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔...
    叶总韩阅读 5,125评论 0 41
  • 一不留神竟然都已经工作四年多了,俨然已经成为了即将被后浪拍死在沙滩上的年纪。脸上的肥肉不知不觉爬上来,时刻提醒...
    TommyHu阅读 294评论 0 2