这篇时间较之前篇章时间靠后,是由于,某一天晚上看完Java编程思想文献之后来不及做笔记了。
以下笔记基本为转载,不是原创
第二章 一切都是对象
目录:
- 2.1 用引用操纵对象
- 2.2 必须由你创建所有对象
- 2.3 永远不需要销毁对象
- 2.4 创建新的数据类型:类
- 2.5 方法、参数和返回值
- 2.6 构建一个Java程序
- 2.7 你的第一个Java程序
- 2.8 注释和嵌入式文档
- 2.9 编码风格
2.1 用引用操纵对象
一切都看作对象,操纵的标识符实际上是对象的一个“引用”,遥控器(引用)操纵电视机(对象),想调控电视,只需通过遥控器,且遥控器是独立存在的。
2.2 必须由你创建所有对象
一旦创建了一个引用,就希望它能与一个新的对象相关联,通常用new操作符来实现这一目的。
String s = new String("Jiancheng");
存储数据的五个地方:
1)寄存器。这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部。
2)堆栈。位于通用RAM(随机访问存储器)中,但通过堆栈指针可以从处理器那里获得直接支持。
堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这是一种快速有效的分配存储方法,仅次于寄存器。
创建程序时,Java程序必须知道存储在堆栈内所有项的确切生命周期,以便上下移动堆栈指针。
3)堆。一种通用的内存池也位于RAM区,用于存放所有的Java对象。
堆不同于堆栈的好处是:编译器不需要知道存储的数据在堆里存活多久时间。
当需要一个对象时,只需用new写一行简单的代码。
用堆进行存储分配和清理可能要比用堆栈进行存储分配需要更多的时间。
4)常量存储。常量通常直接存放在程序代码内部,这样做是安全的,因为它们永远不会被改变。
在嵌入式系统中,常量本身会和其他部分隔离开,所有这种情况下,可以选择将其存放在ROM(只读存储器)中。
5)非RAM存储。如果数据完全存活于程序之外,那么它就不受程序的任何控制,在程序没有运行是也可以存在。
其中两个基本例子是流对象和持久化对象。
在流对象中,对象转化成字节流,通常被发送给另一台机器。
在“持久化对象”中,对象被存放于磁盘上,因此,即使程序终止,它们仍可以保持自己的状态。
堆栈是栈。(重要的事情说三遍,这是第二遍)
堆栈指针若向下移动,则分配新的内存;若向上移动,则释放那些内存。这句话之前一直都不理解,因为大学学习的数据结构中,栈底就是在底部,栈顶就是在顶部,所以堆栈指针向下移动的话,应该是释放内存的,所以这句话错了?当然不是!
linux中一个进程的虚拟内存分布:
图中0号地址在最下边,越往上内存地址越大。
以32位地址操作系统为例,一个进程可拥有的虚拟内存地址范围为0-2^32。分为两部分,一部分留给kernel使用(kernel virtual memory),剩下的是进程本身使用, 即图中的process virtual memory。
普通Java 程序使用的就是process virtual memory.
上图中最顶端的一部分内存叫做user stack. 这就是题目问的 stack(栈). 中间有个 runtime heap。就是题目中的heap(堆). 他们的名字和数据结构里的stack(栈) 和 heap(堆) 几乎没啥关系。
注意在上图中,stack(栈)是向下生长的; heap(堆)是向上生长的。
所以呢,堆栈指针向下移动时分配内存,向上移动时释放内存。
9种基本类型:
基本类型出现的原因:这种类型是小的、简单的变量,不需要用new在堆上分配空间(有特例成员变量的基本类型是在堆上),直接置于堆栈中,这样更高效。
boolean类型所占内存储空间的大小没有明确指定,仅定义为能够取字面值true或false。
高精度数字:
- BigInteger:支持任意精度的整数
- BigDecimal:支持任意精度的定点数
操作与对基本类型所能执行的操作相似,但必须以方法调用方式取代运算符方式来实现。
Java中的数组:
数组会被初始化,而且不能在它的范围之外被访问。这种范围检查,是以每个数组上少量的内存开销及运行时的下标检查为代价(换来安全性和效率)。
2.3 永远不需要销毁对象
作用域:
------------------------------------------------------------------
对象的作用域:
Java的作用和基本类型差别很大,new创建一个Java对象后,它可以存活于作用域之外。只要你需要这个对象,就会一直保留下去,直到垃圾回收器辨别到该对象不会再被引用并释放该对象的内存空间,这样就消除了内存泄漏的问题。
2.4 创建新的数据类型:类
大多数面向对象的程序设计语言习惯用关键子class来表示“我准备告诉你一种新类型的对象看起来像什么样子。
class ATypeName { /* Class body goes here */ }
2.4.1 字段和方法
在Java中你所做全部工作就是定义类,产生那些类的对象,以及发送消息给这些对象。
一旦定义了一个类,就可以在类中设置两种类型的元素:字段(有时被称作数据成员)和方法(有时被称作称成员函数)。
字段可以是任何类型的对象,可以通过其引用与其进行通信;也可以是基本类型中的一种。如果字段是对某个对象的引用,那么必须初始化该引用,以便使其与一个实际的对象相关联。
每个对象都有用来存储其字段的空间;普通字段不能在对象间共享。
class DataOnly { int i; double d; boolean b; }
如何引用一个对象的成员:
在对象引用的名称之后紧接着一个句点,然后在接着是对象内部的成员名称:
objectReference.member
如:
DataOnly data = new DataOnly();
data.i = 47;
data.d = 1.1;
data.b = false;
基本成员默认值
若类的某个成员是基本数据类型,即使没有进行初始化,Java也会确保它获得一个默认值。
基本类型 | 默认值 |
---|---|
boolean | false |
char | 'u0000'(null) |
byte | (byte)0 |
short | (short)0 |
int | 0 |
long | 0L |
float | 0.0f |
double | 0.0d |
这些初始值对你的程序来说,可能是不正确的,甚至是不合法的。所以最好明确地对变量进行初始化。
然而上述确保初始化的方法并不适用于(即并非某个类的字段)。
在某个方法定义中有:
int x;
如果忘记了赋初值,Java会在编译是返回一个错误,告诉你此变量没有初始化。
2.6 构建一个Java程序
static关键字:
下面两种情况需要使用static
- 只想为某特定域分配单一存储空间,而不去考虑究竟要创建多少对象。
- 某个方法不与包含它的类的任何对象关联在一起,就是没有创建对象,也能够调用这个方法。
class StatiTest{ static i = 47; //可以直接StatiTest.i这样调用 }
StatiTest st1 = new StatiTest();
StatiTest st2 = new StatiTest();
其中st1.i和st2.i指向同一存储空间,因此他们具有相同的值47。
同理,调用静态方法的首选方式:ClassName.method()
。如:
class Incrementable { static void increment() { StaticTest.i++; } }
调用方式一:
Incrementable sf = new Incrementable(); sf.increment();
调用方式二:
Incrementable.increment();
2.9 编码风格
驼峰风格:
- 类,每个单词的首字母采用大写
- 方法、字段及对象等,第一个单词的首字母采用小写,其余首字母大写
总结:
本章容易理解,对Java语言及它的一些基本思想有一个总体的认识,大多数知识点也接触过,但容易把细节的地方忘记,多看无碍。