Java简明笔记(七) 异常和断言

异常处理

在Java异常处理中,一个方法可以通过 抛出(throw) 异常来发出一个严重问题的信号。调用链中的某个方法,负责 捕获(catch) 并处理异常。捕获到的异常不仅可以在当前方法中处理,还可以将异常抛给调用它的上一级方法去处理。

异常处理的根本优点是:将错误检测和错误处理的过程解耦。

Java 的异常都派生自 Throwable 类,Throwable 又分为 Error 和 Exception。Error 不是我们的程序所能够处理的,比如系统内存耗尽。我们能预知并处理的错误属于 Exception。Exception又分为 unchecked exception 和 checked exception。 unchecked exception 属于 RuntimeException 。

当然,所有的异常都发生在运行时(Runtime),但是 RuntimeException 派生的子类异常在编译时不会被检查。

阅读更多

Java中的 String

String 的本质

在 Java8 中,分析 java.lang.String 类的源码,可以发现 String 内部维护的是一个 char 数组。同时可以发现,String类被 final 修饰,即不可变的。

1
2
3
4
5
6
7
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];

//...
}

在 Java9 中,将 char 数组优化成了 byte 数组。

1
private final byte value[];
阅读更多

Java简明笔记(六) 集合

集合和集合框架

什么是集合?

集合就是一个放数据的容器,准确的说是放数据对象引用的容器。

Java集合主要可以划分为三个部分:

  1. Collection(包含 List 和 Set )
  2. Map (键值对)
  3. 工具类(Iterator迭代器、Enumeration枚举类、Arrays和VCollections)
阅读更多

Java简明笔记(五) 泛型编程

什么是泛型类

假设我们现在有一个存储字符串字典键值对的类,就像这样

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Entry {
private int key;
private String value;

// 构造函数:int 类型的 key, String 类型的 value
public Entry(int key, String value) {
this.key = key;
this.value = value;
}

public int getKey() { return key; }
public String getValue() { return value; }
}

在这个类中,我们用 int 类型来存储 key 值, 用 String 类型来存储 value 值。

现在,老板要求,除了 int 类型的 key 和 String 类型的 value之外,还得提供其他类型的 key 和 value 。 比如 double 类型的 key, boolean 类型的value。

我们不可能写很多个相似的类,只是换一下类型。8种基本数据类型或许可以这么干,但是存储的是抽象数据类型呢?我们不可能所有类型都写一个对应的类。

为了解决这个问题,我们可以用 Java 泛型: 只写一个类,实例化的时候再写明是什么类型就好了。这就是泛型类。

泛型仅仅是java的语法糖,它不会影响java虚拟机生成的汇编代码,在编译阶段,虚拟机就会把泛型的类型擦除,还原成没有泛型的代码。

阅读更多

Java简明笔记(四) 继承

什么是继承

继承是在现有的类的基础上创建新类的过程。继承一个类,你也就重用了它的方法,而且还可以添加新的方法和域。

举个例子:员工有薪水,管理者有薪水+奖金, 管理者继承员工,增加 bounus 字段和 setBonus 方法即可。这种情况就是管理者类继承了员工类。

1
2
3
4
5
6
7
8
public class Manager extends Employee {
private double bonus;
...

public void setBonus (double bouns) {
this.bonus = bonus;
}
}

Manager类继承了Employee类,除了获得Employee类的变量和方法外,还额外添加了bonus变量和setBonus方法。

阅读更多

Java简明笔记(三) 接口

什么是接口

假设有一种整数序列服务,这种服务可以计算前n个整数的平均值。就像这样:

1
2
3
4
5
public static double average(IntSequence seq, int n){
...
return average
}

我们传入一个序列seq,以及我们想计算这个序列的前n个数,它返回平均数。

然而,这样的序列可以有很多种形式,比如用户给出的序列、随机数序列、素数序列、整数数组中的元素序列……

阅读更多

Java简明笔记(二) 面向对象

Java 创建对象的过程

当我们实例化一个对象时,例如:

1
Person p = new Person();

Java首先会在堆中开辟一块内存空间用来存放这个新的 Person 对象,然后在栈中创建一个引用 p , p 指向堆中的 Person 对象。这样,我们通过 p 就能找到 Person 的内存地址。

之后,我们执行:

1
Person p2 = p;

我们创建了一个新的引用 p2, p2 跟 p 一样,都是保存在栈中,也指向了 Person 对象。当我们改变 p2 的状态, p 也会跟着改变,因为他们指向同一个对象。

阅读更多

Java简明笔记(一) 基础知识

java

Java 与 C++ 的区别

  1. C++支持多重继承,Java不支持,但可以实现多接口。(引申:多重继承菱形问题)
  2. 自动内存管理
  3. java不支持goto语句
  4. 引用与指针:在Java中不可能直接操作对象本身,所有的对象都由一个引用指向,必须通过这个引用才能访问对象本身,包括获取成员变量的值,改变对象的成员变量,调用对象的方法等。而在 C++ 中存在引用,对象和指针三个东西,这三个东西都可以访问对象。其实,Java中的引用和C++中的指针在概念上是相似的,他们都是存放的对象在内存中的地址值,只是在Java中,引用丧失了部分灵活性,比如 Java 中的引用不能像 C++ 中的指针那样进行加减运算。
阅读更多