avatar

Catalog
JAVA编程思想笔记(一)

第二章:一切都是对象

创建句柄

在创建句柄(references)时如果没有初始化,往往会发生错误,如String s; ,因此更安全的做法是在创建句柄的时候进行初始化,String s = "abcd"; 在创建新的句柄时,String s = new String("abcd"); new的意思也就是创建一个新的对象,这条语句不仅仅是创建了一个字符串,而且包含了怎样生成这个字符串的信息。

java的存储方式

​ Java有5种存储方式:寄存器,堆栈,堆,静态存储,常数存储,非RAM式存储。

  1. 寄存器: 最快的存储方式,不同于其他方式,它是直接存储在CPU里面的,但是由于空间非常小,所以要根据需要分配,我们对此没有直接的控制权,在程序中也无法看到。

  2. 栈: 通常是在RAM中,但是通过堆栈指针,可以直接与CPU通信,是一种非常有效且快速的分配方式,指针下移创建内存空间,指针上移释放内存空间。但是由于分配方式灵活性的限制,并不是所有的数据都存储在堆栈中,所以当创建对象时,在堆栈中的只是对象的句柄(references)对象本身并不在堆栈中。

  3. 堆:是一种常规用途的内存池(也在RAM中),其中保存的是JAVA对象,编译器并不知道要分配多少内存空间,在堆里停留多久。当需要一个新的对象时,只需要一个 new ,当这条语句执行时,就会自动在堆中分配空间。

  4. 静态存储:这儿的“静态”(Static)是指“位于固定位置”(尽管也在RAM里)。程序运行期间,静态存储的数据将随时等候调用。可用static关键字指出一个对象的特定元素是静态的。但Java对象本身永远都不会置入静态存储空间。

  5. 常数存储: 常数通常直接置入代码内部,这样是安全的,因为他们永远都不会改变。为了安全考虑,在嵌入式设备中,它们通常是被置入ROM中。

  6. 非RAM存储: 这类数据可以在程序没有运行的时候存在,主要分为两种,流式对象和固定对象,流式对象会变成字节流,发给另外一台机器。而固定对象保存在磁盘中。这些类型的数据可以再需要的时候将它们变成存在于RAM中的对象。

特殊情况:主数据类型 primitive types

Java中采用了与c/c++相同的方法,不用new变量,而是创建一个并非句柄的“自动”变量。这些数据存储在堆栈中。

Primitive type Size Minimum Maximum WapperType
boolean 1-bit - - Boolean
byte 8-bit -128 +127 Byte[1]
short 16-bit -2^15 +2^15–1 Short[1]
int 32-bit -2^31 +2^31–1 Integer
long 64-bit -2^63 +2^63–1 Long
float 32-bit IEEE754 IEEE754 Float
double 64-bit IEEE754 IEEE754 Double
void Void[1]

作用域

在C,C++和JAVA里,作用域是由花括号的位置决定的。

java
1
2
3
4
5
6
7
8
9
10
{
int x = 12;
/* 只有x是有效的 */
{
int q = 96;
/* x和q都有效 */
}
/* 只有x是有效的 */
/* q在作用域之外” */
}

注意尽管在C和C++里是合法的,但在Java里不能象下面这样书写代码:

java
1
2
3
4
5
6
{
int x = 12;
{
int x = 96; /* illegal */
}
}

编译器会认为变量x已被定义。

对象的作用域

JAVA中对象和主数据类型有不一样的存在时间,如下

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

句柄s会在作用域的终点消失,而句柄s指向的对象仍在内存中占用着空间,对此,java引入了垃圾收集器的机制,会查找出不再被引用的对象,释放这些对象占据的内存。

类是自己定义的数据类型,当你定义一个类的时候,可以向类中设置两种类型的元素:成员变量(field)和方法(method)

static关键字

不需要创建对象就可以调用静态的方法或者或者数据,由于static方法不需要创建任何对象,所以不能简单地调用其他那些成员。
例如,下述代码能生成一个static数据成员,并对其初始化:

java
1
2
3
class StaticTest {
Static int i = 47;
}

现在new了两个StaticTest的对象,但他们的值都是47,因为他们引用同一片内存区域。当 i 变化时, st1.i , st2.i 都会同时变化。
静态方法的定义类似

java
1
2
3
class StaticFun {
static void incr() { StaticTest.i++; }
}//调用静态变量不用new对象

由于是静态方法,可以直接调用 incr()
StaticFun.incr();
也可以用典型的方法调用 incr()

java
1
2
StaticFun sf = new StaticFun();
sf.incr();
Author: Jacob
Link: http://yoursite.com/2019/07/25/Java%E7%BC%96%E7%A8%8B%E6%80%9D%E6%83%B3%E8%AF%BB%E4%B9%A6%E7%AC%94%E8%AE%B0%EF%BC%88%E4%B8%80%EF%BC%89/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶