当前位置: 首页 > wzjs >正文

保山 网站建设网站开发预算报表

保山 网站建设,网站开发预算报表,网站建设设计费用,英国做网站的人对问题的解释 1. “字符串常量池存储的是string对象的直接引用,而不是直接存放的对象,是一张string table” 的含义 这句话可以从以下几个方面理解: (1) 字符串常量池的存储内容 直接引用:字符串常量池中存储的是指向实际 Stri…

对问题的解释

1. “字符串常量池存储的是string对象的直接引用,而不是直接存放的对象,是一张string table” 的含义

这句话可以从以下几个方面理解:


(1) 字符串常量池的存储内容
  • 直接引用:字符串常量池中存储的是指向实际 String 对象的引用(即内存地址),而不是直接存储 String 对象本身。
  • 不是直接存放对象:实际的 String 对象仍然存在于堆内存中,字符串常量池仅保存这些对象的引用(类似“索引表”)。

(2) “string table” 的作用
  • 结构:字符串常量池内部通常以哈希表(Hash Table) 的形式实现,称为 string table
  • 功能:通过哈希表快速查找是否存在与某个字符串内容相同的对象:
    • 当程序中出现字符串字面量(如 "hello")时,JVM 会检查 string table 中是否存在该字符串的引用。
    • 如果存在,则直接返回该引用;如果不存在,则创建新对象并将其引用存入 string table

(3) 示例说明
String s1 = "hello"; // 1. 检查常量池是否有"hello",没有则创建并存入
String s2 = "hello"; // 2. 直接返回常量池中的引用,s1和s2指向同一个对象
  • 内存分布
    • 常量池中存储的是 "hello"引用(如地址 0x1000)。
    • 实际的 "hello" 对象在堆内存中,内容包含字符数组 {'h', 'e', 'l', 'l', 'o'}

2. 与缓存的关系

字符串常量池本质上是一种缓存机制,其核心目的是复用已有对象,从而节省内存和提升性能:


(1) 缓存的实现原理
  • 避免重复创建对象:当多个相同字符串被使用时,通过常量池共享同一个对象,减少内存占用。
    String s3 = new String("world"); // 1. 在堆中创建新对象,不放入常量池
    String s4 = new String("world"); // 2. 再次创建新对象,导致内存浪费
    System.out.println(s3 == s4);    // false(两个不同对象)
    
  • 通过 intern() 手动缓存:若希望 new String() 创建的对象也进入常量池,需调用 intern() 方法:
    String s5 = new String("test").intern(); // 将对象加入常量池
    String s6 = "test";                      // 直接指向常量池中的对象
    System.out.println(s5 == s6);            // true(同一个对象)
    

(2) 缓存的优势
  • 节省内存:相同内容的字符串只占用一份内存空间。
  • 提升性能
    • 快速查找:通过哈希表(string table)快速判断字符串是否存在。
    • 避免垃圾回收压力:减少短命对象的频繁创建和销毁。

(3) 与 JVM 内存区域的关系
  • JDK 7 之前:字符串常量池位于方法区(Method Area)
  • JDK 7 及以后:字符串常量池移至堆内存(Heap),与普通对象存储在同一区域,但通过 string table 管理引用。

3. 总结
  • 字符串常量池的本质:通过存储对象的引用(而非对象本身)实现一种缓存机制,利用哈希表(string table)快速复用相同内容的字符串对象。
  • 与缓存的关系:它是一种内存优化策略,通过减少对象重复创建来节省内存和提升性能,类似于其他缓存机制(如 Integer 的缓存区间)。

常见疑问解答
  1. 为什么 new String("abc") 不进入常量池?

    • 因为 new 总是创建新对象,且不自动调用 intern()。若需缓存,需显式调用 intern()
  2. intern() 的作用是什么?

    • 将字符串对象加入常量池,确保相同内容的字符串共享同一引用。
  3. 字符串拼接是否会影响常量池?

    • 字符串拼接(如 "a" + "b")会生成新对象,但若结果是编译期可知的字面量,则会被自动加入常量池:
      String s = "a" + "b"; // 编译时合并为"ab",直接使用常量池中的对象
      

通过理解字符串常量池的设计,可以更好地优化代码中字符串的使用,避免内存浪费并提升性能。

例子解释

1. 缓存范围内的值(-128 到 127)
Integer a = 100;  // 自动装箱,调用 Integer.valueOf(100)
Integer b = 100;  // 再次调用 Integer.valueOf(100),返回缓存中的同一个对象
System.out.println(a == b);  // 输出 true(指向同一对象)
  • 原因
    ab 的值 100 在缓存范围内(-128 到 127)。
    Integer.valueOf(100) 会直接从缓存数组中获取已存在的 Integer 对象,因此 ab 指向同一个对象,== 比较返回 true

2. 超出缓存范围的值(如 128 或 -129)
Integer c = 128;  // 自动装箱,调用 Integer.valueOf(128)
Integer d = 128;  // 调用 Integer.valueOf(128),超出默认缓存范围
System.out.println(c == d);  // 输出 false(指向不同对象)
  • 原因
    128 超出默认缓存范围(-128 到 127)。
    Integer.valueOf(128)新建一个 Integer 对象,因此 cd 是两个不同的对象,== 比较返回 false

3. 使用 new 创建对象(绕过缓存)
Integer e = new Integer(100);  // 显式 new 对象,绕过缓存
Integer f = new Integer(100);  // 再次 new,创建新对象
System.out.println(e == f);    // 输出 false(即使值相同,也是不同对象)
  • 原因
    使用 new 关键字会直接创建新对象,完全绕过缓存机制。因此 ef 是不同的对象,== 返回 false

关键点总结

场景行为== 结果原因
值在缓存范围内(如 100)自动装箱调用 Integer.valueOf(),返回缓存中的同一个对象。trueab 指向同一对象。
值超出范围(如 128)自动装箱调用 Integer.valueOf(),但超出缓存范围,因此每次新建对象。falsecd 是不同的对象。
使用 new 创建对象显式调用构造函数,绕过缓存,每次创建新对象。falseef 是不同的对象。

补充说明

1. 如何比较值的大小?
  • 使用 equals() 方法
    System.out.println(c.equals(d));  // 输出 true(比较值,而非引用)
    System.out.println(e.equals(f));  // 输出 true(值相同)
    
  • 避免 == 比较
    == 比较的是对象的引用(内存地址),而 equals() 比较的是对象的值。
2. 缓存范围的调整
  • 通过 JVM 参数调整
    可以通过 -XX:AutoBoxCacheMax=200 或设置系统属性 java.lang.Integer.IntegerCache.high=200 来扩展缓存范围。
    示例
    // 假设将缓存范围调整为 -128 到 200
    Integer g = 150;  // 自动装箱,命中缓存
    Integer h = 150;  // 返回缓存中的对象
    System.out.println(g == h);  // 输出 true
    

完整代码示例

public class IntegerCacheExample {public static void main(String[] args) {// 场景1:值在缓存范围内Integer a = 100;Integer b = 100;System.out.println("a == b: " + (a == b));  // true// 场景2:值超出缓存范围Integer c = 128;Integer d = 128;System.out.println("c == d: " + (c == d));  // false// 场景3:使用 new 创建对象Integer e = new Integer(100);Integer f = new Integer(100);System.out.println("e == f: " + (e == f));  // false// 使用 equals 比较值System.out.println("c.equals(d): " + c.equals(d));  // trueSystem.out.println("e.equals(f): " + e.equals(f));  // true}
}

输出结果

a == b: true
c == d: false
e == f: false
c.equals(d): true
e.equals(f): true

通过这个例子,可以清晰地看到 Integer 缓存机制的作用和不同场景下的行为差异。

http://www.dtcms.com/wzjs/572166.html

相关文章:

  • 聊城市建设局网站怎么查网站备案号
  • 上海建设工程招投标网站wordpress 登陆访问
  • 湘潭公司做网站河南工程建设
  • 旅游网站建设的方法wordpress切换回老的编辑器
  • 国外房产中介网站上海网站建设 网站开发
  • 选服务好的网站建设公司微商广告推广
  • 广州网站建设公司怎么挑选想自学广告设计怎么学
  • 提供营销网站建设公司代注册公司要多少钱
  • 公司网站网站不备案室内设计网上接单
  • 建完网站怎样维护怎么让网站能被百度到
  • 发外链的网站排名职业做网站游戏的
  • 域名备案与网站不一致长宁集团网站建设
  • 加盟网站制作运营.net开发网站怎么样
  • 学校网站制作素材做网站的分辨率
  • 如何利用淘宝建设网站挣钱温州平台网站建设
  • 网站开发销售话术网站建设 招聘需求
  • 网站开发组合 所有组合郑州制作网站
  • 深圳手机网站建设哪家好wordpress这么写一个api
  • 有哪些可以做包装袋的网站洛阳哪里做网站
  • 做网站价位个人网站做支付宝收款
  • 专业建站公司报价北京信息网站建设
  • 网站ui设计报价单同步wordpress到微信
  • 网站导航设计原则成都房产信息查询官方网站
  • 百度快照怎么没有了南昌seo排名技术
  • 如何创建电子商务网站南京网站推广哪家便宜
  • 南昌网站建设报价单在建工程项目查询
  • 中国建设银行网站登录不了建设英文网站多少钱
  • 加油站网站建设常用网站推荐
  • 书店网站建设规划书中国网站用Cn域名
  • 嘉盛建设集团官方网站做一个信息发布网站要多少钱