On Java8读书笔记

Objects EveryWhere

使用Reference掌控对象

掌控一个对象有两种不同的方式:直接掌控变量本身 or 间接掌控一个"通道",通过"通道"可以掌控对象

在Java中,我们通过间接的方式掌控对象,而这个"通道"就是Reference

Reference不同于对象本身,对象本身往往是"臃肿的"(对象内包括字段和方法),而Reference则是"轻巧的"

一个Reference在每一时刻只能对应一个对象,但是在线性的时间上,可以对应不同的对象(即可以改变Reference的指向)

使用new创建对象

那么要如何创建一个对象呢?

在Java中使用new关键字创建一个新的对象,例如:String s = new String("hello")

new不仅仅表示为’s’建立"通道"连接到一个String对象上,同时也创建了一个String对象

数据存储的地方

了解数据在计算机中的存储方式也许能让我们进一步理解对象和Reference之间抽象的关系!

数据存储的地方有五种:

  1. Register:这是最快[^1]的存储方式,然而由于Register的数量实在太少,因此为了防止程序员随意的使用而造成一些列不可预估的结果,Java并不允许我们直接使用Register,甚至我们都无法在程序中感知到它的存在
  2. stack:栈是另一种常见的存储空间,其中的数据后进先出[^2],同时它也是效率和速度仅次于Register的。对于存储在栈上的数据,Java必须知道它的生命周期,这种限制降低了我们的效率。一般来说,Reference和基本数据类型存储在栈上
  3. heap:不同于栈,Java并不需要明确知道堆中数据的生命周期,这使得我们的编程更加灵活,然而这种灵活性也需要付出代价:开辟和回收堆空间时需要耗费更多的时间。不过在Java中这种代价在逐步被优化。可以说所有的对象都存储在堆中
  4. constant storage:常量一般都直接出现在程序中,由于它们的不可变性,它们往往都非常的安全,这些数据则存储在constant storage中
  5. Non-RAM:存储于硬盘或流中的数据往往都在Non-RAM中,它们往往都完全独立于程序之外

基本数据类型

虽然Java强调万物皆对象,但是Java中也有基本数据类型,不同于包装类(Integer、Character等)基本数据类型往往更加的轻便、高效(存储于stack),并且由于它们拥有固定的大小,所以在不同的机器中,它们都可移植。Java8以上实现了自动装包和拆包,因此可以将基本数据类型和包装类直接运算

数组

许多拥有数组的编程语言都将数组作为一个块存储于stack中,加入一个程序数组索引超出了规定的范围,很有可能会访问到一块不属于数组的内存,从而造成不可预估的后果

在Java中,将数组视作一个对象,存储于heap中,我们则使用Reference去掌控数组,如果使用了超出范围的索引,则会在编译阶段报错[^3]

创建了数组以后,若没有直接给数组的元素赋值,那么Java会为每个元素赋上默认值,对象是null,其它的是0

数据回收

作用域

同样于其它语言,Java使用{}表示一个作用域,当作用域结束时,stack上的数据会被释放

heap上的数据并不会随着作用域的结束而结束,它会继续存在于程序中,直到一个垃圾回收装置检测到它不再被使用,才会被回收

在c++中你可能会看到如下代码

`outer:
{
    int x = 10;
    `inner:
    {
        int x = 9;
        cout << x;
    }
    cout << x;
}

c++中采用了’hide’的机制,第一次打印的值是9,第二次是10。在inner中创建了一个x变量(outer中的x隐藏),因此第一次打印9,而当{}结束后,x又变回了outer中的x,因此打印10。然而在Java中这样的语句是非法的,编译器会报错。

Java中无需我们手动是否内存空间,它有着优秀的内存回收机制,尽管也没那么智能(bushi),但它也让Java程序员比c++程序员少掉很多头发

一个类(class)包含了两个部分:字段与方法

可以这样理解,字段就是类本身的属性,例如一个人的身高、体重、年龄等;而方法则是类本身的行为,例如一个人可以走路、说话

字段如果没有被显示的定义,则会赋给它默认值(o或null)

字段可以使用.来访问:在Reference后面跟上.和字段名,方法的使用也同字段一样。不过我们一般会将字段设置为private(类外不可访问),这与程序的安全性相关

也许一个习惯于使用c++的程序员在刚接触到Java时会犯这样的错:在类外写方法,然后发现无法调用方法,查阅了无数资料发现了一个可怕的事实,是的,Java中所有方法都必须定义在类中!Java确实是一个更加纯粹的面向对象语言,在Java中万物皆对象

那么随之而来的新问题就是,如果我想使用一个和类的实例毫无关联的方法怎么办?或者说使用一个毫无关联的字段怎么办?

static关键字呼之欲出,使用static关键字在任何的方法或字段之前,可以让他们成为一个被同一类所有不同实例所共享的"共享单车",如果你想调用它们,直接使用类名.方法或字段即可

  • 52
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沅筱

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值