String 的本质
在 Java8 中,分析 java.lang.String 类的源码,可以发现 String 内部维护的是一个 char 数组。同时可以发现,String类被 final
修饰,即不可变的。
1 | public final class String |
在 Java9 中,将 char 数组优化成了 byte 数组。
1 | private final byte value[]; |
在 Java8 中,分析 java.lang.String 类的源码,可以发现 String 内部维护的是一个 char 数组。同时可以发现,String类被 final
修饰,即不可变的。
1 | public final class String |
在 Java9 中,将 char 数组优化成了 byte 数组。
1 | private final byte value[]; |
集合就是一个放数据的容器,准确的说是放数据对象引用的容器。
Java集合主要可以划分为三个部分:
假设我们现在有一个存储字符串字典键值对的类,就像这样
1 | public class Entry { |
在这个类中,我们用 int 类型来存储 key 值, 用 String 类型来存储 value 值。
现在,老板要求,除了 int 类型的 key 和 String 类型的 value之外,还得提供其他类型的 key 和 value 。 比如 double 类型的 key, boolean 类型的value。
我们不可能写很多个相似的类,只是换一下类型。8种基本数据类型或许可以这么干,但是存储的是抽象数据类型呢?我们不可能所有类型都写一个对应的类。
为了解决这个问题,我们可以用 Java 泛型: 只写一个类,实例化的时候再写明是什么类型就好了。这就是泛型类。
泛型仅仅是java的语法糖,它不会影响java虚拟机生成的汇编代码,在编译阶段,虚拟机就会把泛型的类型擦除,还原成没有泛型的代码。
继承是在现有的类的基础上创建新类的过程。继承一个类,你也就重用了它的方法,而且还可以添加新的方法和域。
举个例子:员工有薪水,管理者有薪水+奖金, 管理者继承员工,增加 bounus 字段和 setBonus 方法即可。这种情况就是管理者类继承了员工类。
1 | public class Manager extends Employee { |
Manager
类继承了Employee
类,除了获得Employee类的变量和方法外,还额外添加了bonus变量和setBonus方法。
假设有一种整数序列服务,这种服务可以计算前n个整数的平均值。就像这样:
1 | public static double average(IntSequence seq, int n){ |
我们传入一个序列seq,以及我们想计算这个序列的前n个数,它返回平均数。
然而,这样的序列可以有很多种形式,比如用户给出的序列、随机数序列、素数序列、整数数组中的元素序列……
当我们实例化一个对象时,例如:
1 | Person p = new Person(); |
Java首先会在堆中开辟一块内存空间用来存放这个新的 Person 对象,然后在栈中创建一个引用 p , p 指向堆中的 Person 对象。这样,我们通过 p 就能找到 Person 的内存地址。
之后,我们执行:
1 | Person p2 = p; |
我们创建了一个新的引用 p2, p2 跟 p 一样,都是保存在栈中,也指向了 Person 对象。当我们改变 p2 的状态, p 也会跟着改变,因为他们指向同一个对象。