【Java编程思想】阅读笔记

万物皆对象

Java 是一种更纯粹的面向对象编程语言。Java 语言假设你只进行面向对象编程。

对象操纵

Java 利用万物皆对象的思想和单一一致的语法方式来简化问题。虽万物皆可为对象,但我们所操纵的标识符实际上只是对对象的“引用” 。

数据存储

有5个不同的地方可以存储数据:

  1. 寄存器(Registers)最快的存储区域,位于 CPU 内部。然而,寄存器的数量十分有限,所以寄存器根据需求进行分配。我们对其没有直接的控制权,也无法在自己的程序里找到寄存器存在的踪迹(另一方面,C/C++ 允许开发者向编译器建议寄存器的分配)。
  2. 栈内存(Stack)存在于常规内存 RAM(随机访问存储器,Random Access Memory)区域中,可通过栈指针获得处理器的直接支持。栈指针下移分配内存,上移释放内存。这是一种仅次于寄存器的非常快速有效的分配存储方式。创建程序时,Java 系统必须知道栈内保存的所有项的生命周期。这种约束限制了程序的灵活性。因此,虽然在栈内存上存在一些 Java 数据(如对象引用),但 Java 对象本身的数据却是保存在堆内存的。
  3. 堆内存(Heap)这是一种通用的内存池(也在 RAM 区域),所有 Java 对象都存在于其中。与栈内存不同,编译器不需要知道对象必须在堆内存上停留多长时间。因此,用堆内存保存数据更具灵活性。创建一个对象时,只需用 new 命令实例化对象即可,当执行代码时,会自动在堆中进行内存分配。这种灵活性是有代价的:分配和清理堆内存要比栈内存需要更多的时间(如果可以用 Java 在栈内存上创建对象,就像在 C++ 中那样的话)。随着时间的推移,Java 的堆内存分配机制现在已经非常快,因此这不是一个值得关心的问题了。
  4. 常量存储(Constant storage)常量值通常直接放在程序代码中,因为它们永远不会改变。如需严格保护,可考虑将它们置于只读存储器 ROM (只读存储器,Read Only Memory)中。
  5. 非 RAM 存储(Non-RAM storage)数据完全存在于程序之外,在程序未运行以及脱离程序控制后依然存在。两个主要的例子:(1)序列化对象:对象被转换为字节流,通常被发送到另一台机器;(2)持久化对象:对象被放置在磁盘上,即使程序终止,数据依然存在。这些存储的方式都是将对象转存于另一个介质中,并在需要时恢复成常规的、基于 RAM 的对象。Java 为轻量级持久化提供了支持。而诸如 JDBC 和 Hibernate 这些类库为使用数据库存储和检索对象信息提供了更复杂的支持。

    基本类型

    Java 的基本类型的创建并不是通过 new 关键字来产生。通常 new 出来的对象都是保存在堆内存中的
    对于这些基本类型的创建方法,Java 使用了和 C/C++ 一样的策略。也就是说,不是使用 new 创建变量,而是使用一个“自动”变量。 这个变量直接存储”值”,并置于栈内存中,因此更加高效。
    Java 确定了每种基本类型的内存占用大小。 这些大小不会像其他一些语言那样随着机器环境的变化而变化。这种不变性也是 Java 更具可移植性的一个原因
基本类型 大小 最小值 最大值 包装类型
boolean Boolean
char 16 bits Unicode 0 Unicode 2^16 -1 Character
byte 8 bits -128 +127 Byte
short 16 bits - 2^15 + 2^15 -1 Short
int 32 bits - 2^31 + 2^31 -1 Integer
long 64 bits - 2^63 + 2^63 -1 Long
float 32 bits IEEE754 IEEE754 Float
double 64 bits IEEE754 IEEE754 Double
void Void

所有的数值类型都是有正/负符号的。布尔(boolean)类型的大小没有明确的规定,通常定义为取字面值 “true” 或 “false” 。基本类型有自己对应的包装类型,如果希望在堆内存里表示基本类型的数据,就需要用到它们的包装类.

数组的存储

Java 的设计主要目标之一是安全性。在 Java 中,数组使用前需要被初始化,并且不能访问数组长度以外的数据。这种范围检查,是以每个数组上少量的内存开销及运行时检查下标的额外时间为代价的,但由此换来的安全性和效率的提高是值得的。(并且 Java 经常可以优化这些操作。
当创建对象数组时,实际上是创建了一个引用数组,并且每个引用的初始值都为null。在使用该数组之前,必须为每个引用指定一个对象。还可创建基本类型的数组。编译器通过将该数组的内存全部置零来保证初始化。

对象清理

对象作用域

  1. {
  2. String s = new String("a string");
  3. }
  4. // 作用域终点

引用 s 在作用域终点就结束了。但是,引用 s 指向的字符串对象依然还在占用内存。
Java 的垃圾收集器会检查所有 new 出来的对象并判断哪些不再可达,继而释放那些被占用的内存,供其他新的对象使用。也就是说,我们不必担心内存回收的问题了。

类的创建

基本数据类型默认值

对象的字段在初始化时会被赋予默认值。方法内的变量则不会,如果不进行赋值操作将无法通过编译。

方法使用

在 Java 中,方法决定对象能接收哪些消息。方法的基本组成部分包括名称、参数、返回类型、方法体。
方法名和参数列表统称为方法签名(signature of the method)。签名作为方法的唯一标识。
调用方法的行为有时被称为向对象发送消息。面向对象编程可以总结为:向对象发送消息。

程序编写

命名可见性

Java 创建者希望我们反向使用自己的网络域名,为一个类库生成一个明确的名称。
空目录填充了深层次结构,它们不仅用于表示反向 URL,还用于捕获其他信息。这些长路径基本上用于存储有关目录中的内容的数据。

static关键字

类是对象的外观及行为方式的描述。通常只有在使用 new 创建那个类的对象后,数据存储空间才被分配,对象的方法才能供外界调用。
当 static 关键字修饰方法时,它允许我们无需创建对象就可以直接通过类的引用来调用该方法。

编码风格

Java 编程语言编码规范(Code Conventions for the Java Programming Language) 要求类名的首字母大写。 如果类名是由多个单词构成的,则每个单词的首字母都应大写(不采用下划线来分隔)例如:

  1. class AllTheColorsOfTheRainbow {
  2. // ...
  3. }

有时称这种命名风格叫“驼峰命名法”。对于几乎所有其他方法,字段(成员变量)和对象引用名都采用驼峰命名的方式,但是它们的首字母不需要大写。代码示例:

  1. class AllTheColorsOfTheRainbow {
  2. int anIntegerRepresentingColors;
  3. void changeTheHueOfTheColor(int newHue) {
  4. // ...
  5. }
  6. // ...
  7. }

在 Oracle 的官方类库中,花括号的位置同样遵循和本书中上述示例相同的规范。


转载自个人博客:https://fusangjie.club/