从C语言理解JAVA(1)- String的原理

问到Java中 String 的原理,那么连Java新人都可以夸夸其谈,什么静态变量,常量池,总能给出一个看似逻辑闭环的答案。

但是,当你继续追问,那么常量池是什么,常量池在哪里时,那么接下来的答案可能就不是那么的统一了。

众所周知,Java语言本身诞生自C语言,其中很多非常基础的底层代码也诞生自C语言。如果脱离C语言去单独解释Java,那么如同用油彩画给Java画了一副结构图,远看还不错,近看却一篇模糊。此文主要是给Javaer回答一些比较让人疑惑的问题,并不会涉及具体源码解析。

下面开始正文。

一. C语言中的字符串

此部分给C语言小白,或者C语言基础较差的人看。

C语言中当然没有 String 这种封装好的字符串类型,但这并不代表C中没有字符串。

C中的字符串由字符数组实现,大致是这样的:

char string[10] = “abcde”;

char string[10] = [‘a’,‘b’,‘c’];

这两其实是一样的,其和C中普通数组是有相同点的,比如在 string 变量中实际上存储的是 数组内容首元素所在的地址。

比如以上代码中,string变量存放的都是 ‘a’ 所在内存空间的地址。

二. 常量池是什么?

在C语言中,数组是静态变量,其内容是常量,存放在C语言规定的静态存储区内,且数组内容是存放在 连续 空间中的,而不是像链表一样,到处都存有内容的碎片。

所以,所谓Java的常量池概念,本质上并不是一个Java概念,是一个C的概念。

那么为什么会有常量池这个词呢?书中写的都错了吗?

其实你仔细去看Java的书,从Jvm到Java语言的解析,没有哪本书真正的解释过什么是常量池。

这是因为要降低Java的学习成本,如果一个人学习Java之前需要学习,其它语言,那真的太可怕了,估计届时Java早就被淘汰了。

而且Java本身的应用也不需要你了解那么多。

不过现在面试真的太卷了,我还是建议各位准备入坑的同学把C语言好好看看,尤其是喜欢刨根问底的人。

说远了,拉回来。

三. Java中的字符串 - String

没错,本质上Java的字符串就是套用的C语言的字符串的做法,所以C语言字符串的坑,Java也有,比如字符串是个静态变量这事。

看过 String类 源码的人知道,其value是存放在一个 private final byte[] 中的,与C不同的是垃圾回收机制对两种语言的影响,C中的数组不会受到任何垃圾回收系统的影响(自己手写垃圾回收器除外),但是Java中的数组确实有可能被回收。

那么在有垃圾回收系统的Java中,如何搞出与C语言中用法相似的数组?(即做出一个静态变量)

因此加上了 final,在jvm进行具体处理的时候,把其放在了C中的静态存储空间中。

(C中的存储空间大致只分为静态存储空间和动态存储空间,jvm中对于内存的划分本身是虚拟的,因此你可以看到jdk6之后,jvm内存划分变动并不小。一个有着庞大用户群的语言敢于对底层做如此大的变动,就是因为jvm内存部分本质是虚拟的,是硬性规划的,千万不要把jvm和硬件结构联系起来!而jvm的内存结构主要建立在C中动态内存部分的,这部分以后可能会说。)

(一般方式创建的数组,本质上还是一个对象的形式,所以这里的数组也类似。)

很多人容易把是否静态,是否变量,生命周期,作用域混淆,这是学习Java的难点之一。

所以在解释 String 为什么是静态变量的时候,有 final修饰 确实正确,但不完全正确,因为final只是对 value数组 生命周期的修饰。

因为 String的内容 存放在 常量池 中,这也是一个似是而非的答案,至少不够深入。

那么我认为较为完整的回答是:

1.String的内容 存放在 String类 内部的 value数组 上。

2.java源自于C语言,其核心也是C语言,而因为java比C多了一个垃圾回收器,因此导致双方在数组处理上出现了不同,比如数组生命周期上。

3.为了保证 String 本身有着和 C中 char字符数组(即C中字符串)相似的特性,故加上了final修饰,锁定其生命周期,使其不会被回收。

4.加了final的变量会被存放在常量池中,Java中的常量池可以理解成C中的静态存储区,final数组 会被存储于其中的一片连续内存空间中。

5.最终因为jvm在具体实现时是以C语言为核心进行实现,而C中的数组为静态变量,因此 String类 本身也是静态变量。

其实同理可以解释ArrayList,其表面上也是利用 final数组 来存储内容,但底层实际上是使用了C语言的数组进行存储。

Java的 普通数组 与 final数组 本质并不一样,一个是系统自带语法,一个本质上使用C语言的数组。

而Java源码更倾向于使用 final数组 的原因,就是高效,缺点很明显,其放在C中静态存储区域,这部分是Java垃圾回收器无法进行回收的部分,或者说,很难进行回收的部分。

以上只用于个人理解,并不用于面试!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值