《java编程思想》读书笔记——第二章2.2所有的对象都必须创建(对象初始化、如何使用java可以使用的对象空间、基础类型、java数组安全性)

2.2所有的对象都必须创建

一般而言,我们创建完句柄后,希望他与一个新对象相连,都会使用new关键字,其意义可以理解为“把我变成对应的新的类型”

String s = new String("初始值");

在此处,new +String(),可以理解为,把我根据String的该构造方法String(“初始值”);变成一个字符串类型

2.2.1保存到何处

在此前详细谈论过jvm的内存结构,在此处,我们对可以存放数据的空间的具体如何使用、如何存入数据的的方式进行讨论
一类:根本不存放对象,其使用分配由java引擎控制
(1)寄存器/程序计数器
是存储最快的程序,但是因为大小有限,我们并没有控制的权利,通常用于配合多线程进行数据的存放线程的具体书签
(2)栈
速度仅次于寄存器,由于之前提到的算法限制(需要准确定义大小和具体存在时间),对象不会存放于其中,继而我们没有直接控制权力,通常来说,执行引擎将会为每个方法所使用的数据在栈中创建栈帧在其中管理
(3)元空间
存放静态数据、常量及class文件的元数据,其中并不存放对象
二类:可以存放对象由我们进行配置
(1)堆
没有栈的限制,是对象的主要存放处,我们想要将对象置入时只需使用new关键字则会为其配备空间,当然,比栈灵活的代价就是慢
(2)非RAM存储
并不处于JVM内存中,独立于程序控制范围之外。最常见的两类对象为
1.流式对象(I/O对象)
很好理解,一般而言他们会作为字节流,以一种文件的形式存放在文件之中
2.固定对象*
对于某些有价值,希望能够保存,可以通过一些手段将他们在程序结束运行也能够留存下来,且在需要时能够在下次运行时使它恢复到正常在jvm中运行的状态

pass: 我无法查到使用这个名字且符合其特征的具体使用例,原本我认为应该指的是直接内存,但是根据描述特征以及对外内存的加入时间,此处应该指的是另一种用法,而我根据这个词进行查询时,往往只能得到原书的原话,我个人认为,由于该种方案可以直接通过把对象的信息存放在数据库里达成这种效果,可能这种固定对象可以使用的范围较少
3.直接内存/堆外RAM空间
我们可以通过两种方式创建对外对象:
1.使用unsafe类

public class UnsafeTest {

    public static void main(String[] args) {
        Unsafe unsafe = Unsafe.getUnsafe();
        unsafe.allocateMemory(1024);
        unsafe.reallocateMemory(1024, 1024);
        unsafe.freeMemory(1024);
    }
}

2.使用ByteBuffer类

public class TestDirectByteBuzffer {

    public static void main(String[] args) throws Exception {
        ByteBuffer buffer = ByteBuffer.allocateDirect(10 * 1024 * 1024);
    }
}

2.2.2特殊情况:主要类型(基础数据类型)

java将某一部分特殊的,频繁的被使用,且大小可确定的数据类型规划为基础数据类型,这种类型在使用其他普通对象用于创建句柄的语句时,不再是创建句柄而是普通的定义一个自动变量,也就是,句柄中不存放地址而改为存放这些基础变量,并置于栈帧之中,包括:

主类型大小 最小值 最大值 封装器类型
boolean1 位 - - Boolean
char16 位 Unicode 0 Unicode 2 的 16 次方-1 Character
byte8 位 -128 +127 Byte(注释①)
short16 位 -2 的 15 次方 +2 的 15 次方-1 Short(注释①)
int32 位 -2 的 31 次方 +2 的 31 次方-1 Integer
long64 位 -2 的 63 次方 +2 的 63 次方-1 Long
float32 位 IEEE754 IEEE754 Float
double64 位 IEEE754 IEEE754 Double

这些主要类型有封装器(wrapper)类的概念——也就是如果想要在堆内存中存放一个表示主要类型的对象爱你个,就需要用封装器(wrapper)类来实现

char c = 'x';
Character C = new Character('c');
2.2.2.1高精确类型

指的是BigDecimal与BigInteger,本质上可以说他们是类似于Integer的一种封装器类型(毕竟是存放于堆内存中的基础数据),但是他们没有自己对应的“主类型”
对于他们两个来说:
1.int和float能做的,BigDecimal与BigInteger一样可以做
2.不能进行计算,取而代之,需要使用方法对他们进行操作
3.这两个类可以表达任意进度的数,且运算时不需要担心损失数字(Long可能在计算时溢出,Double会有精确性问题)

2.2.3数组

数组是所有语言都会提供的一种功能,在C和C++中,数组作为容器实际上十分危险,其实现的底层本质只是连续的内存块,且没有进行安全限制,很有可能出现越界访问(指针很有可能会操作到预想不到的地方),或者未初始化就使用(很有可能分配的空间里的数据还未清空初始化就被使用了)
在Java中,数组是一类特殊的对象,对这些问题都进行了处理:
1.越界访问:
在java中数组被生成后,将会自动检测是否进行了越界访问——自然在这种配置下,将会支付一定的额外性能作为代价
2.初始化:
在java中创建数组Integer []array,实际创建的只是一个句柄数组,其会被自动赋值一个特殊值null(空),当java在发现一个句柄的值为null则能够判断他还没有一个具体指向的对象,从而在运行期间报错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值