JAVA编程思想

第二章 一切都是对象

java中创建的对象存储到了什么地方
  • 寄存器:这是最快的存储区
  • 堆栈:位于通用RAM中
  • 堆:一种通用内存池,用于存放所有Java对象
  • 常量存储:直接放在程序代码内部
  • 非RAM存储:数据存储活在程序之外,不受任何程序控制。流对象:对象转化成字节流,发送给另一台机器;持久化对象,对象放在磁盘上。
java中的堆、栈、常量池

栈、堆都是java在RAM中用来存放数据的地方,是由java自动管理的。

  • 栈:存取速度比堆要快,仅次于CPU中的寄存器,栈内存中的数据是可以共享的;缺点是栈中的数据大小和生存期是确定的,缺乏灵活性
    举例:int a=3;
    首先在栈中创建一个变量为a的引用,然后查找有没有字面值为3的地址,如果没有,就开辟一个存放3这个字面值的地址,然后将a指向3的地址;如果有,则不用开辟3字面值的地址,直接指向地址。
  • 堆:所有用new xxx()创建的对象都在堆中存储,垃圾回收机制会动态的回收不再使用的数据;缺点是动态分配内存,存储速度慢。
  • 常量池:用来存放字符串常量和基本常量。
  • 关于String str="abc"的内部工作:
  1. 首先定义一个String类型的str变量存放在栈中
  2. 然后在常量池中查找是否存在内容为“abc”的对象
  3. 如果不存在,则在常量池中创建内容为“abc"的对象,并将str引用这个对象
  4. 如果存在,则str直接引用这个对象
  • 关于String str=new String(“abc”);的内部工作
  1. 首先定义一个String类型的str变量存放在栈中
  2. 然后在堆(不是常量池)中创建一个指定的对象,并让str指向这个对象
  3. 在常量池中查找是否存在内容为"abc"的字符串对象
  4. 如果不存在,则在常量池中创建内容为"abc"的字符串对象,指向常量池中的对象
  5. 如果存在,则让new出来的字符串对象与常量池中的对象联系起来,指向常量池中的对象
    对于字符串:对象的引用变量都是存储在栈中,如果在编译器创建好的话(直接用双引号定义的),就放在常量池中;如果是运行期(new)出来的话,就放在堆中。常量中的字符串对象永远自由一份,而堆中的字符串对象有多份
    以上,就很好的解释了一个面试题:String s = new String(“abc”);产生几个对象?答:一个或两个,如果常量池中原来没有”abc”,就是两个。

高精度数字

java中数字精度丢失的原因:

计算机进行的是二进制运算,我们输入的十进制会在计算机中转化成二进制,进行运算后再转化成十进制输出。然而double和float在进行二进制转化的时候,有些数字不能够完全转化,只能够无限的接近原本的值

所以java提供了两个高精度计算的类:BigInteger和BigDecimal。能够计算任意精度、任意大小的数。

java中的垃圾回收机制

java中有一个垃圾回收器,用来监视new创建的所有对象,并辨别那些不再被使用的对象。随后,释放这些对象的内存空间,以便供其他新的对象使用,这样就消除了”内存泄露“。

static关键字

当声明一个事物是static时,就意味着这个域或者方法不会与包含它的那个类的任何对象实例关联在一起。所以,即是从未创建过某个类的任何对象或方法,也可以用static访问static域。

引用static变量有两种方法:一种是实例化一个对象,通过对象类调用;另一种是直接通过类名.方法/属性进行调用。

static字段对每个类来说只有一份存储空间,而非static字段则是对每个对象有一个存储空间。