【代码】

 public class BufferPoolDemo {
public static void main(String[] args) {
Integer i1=127;
Integer i2=127;
System.out.println(i1==i2);
System.out.println("------------"); Integer i3=128;
Integer i4=128;
System.out.println(i3==i4);
System.out.println("------------");
}
}

【运行结果】

 true
----------------------------------
false
----------------------------------

【问题】

为什么一个为true,一个为false呢?为何不是true,true,或false,false呢?

【分析】

1、Integer在定义一个数据对象时,在直接赋值这种情况下(Integer i1=127;而不是new出来的),当赋值数据在byte数据取值范围内时,会先去方法区中的Byte常量池中去找有没有127这个值,如果有,直接将这个值得引用赋值给i1,如果没有的话就分配一个内存空间,然后再把引用赋值给i1。当然这里常量池中没有127这个值,那么久直接给127分配一个空间,然后将其引用赋值给i1;同理,Integer i2=127;时会在缓冲池中找到这个值,那么直接将这个值得引用给i2,所以i1和i2的地址值都是相同的,所以输出为true。

2、由于128没在byte数据取值范围内,Integer i3=128;Integer i4=128;等同于Integer i3=new Integer(128);Integer i4=new Integer(128);那么先去堆中各自开辟一个空间,并分别将其引用赋值给i3,i4,同时也会去常量池中找是否有128这个值,若有,直接将其引用赋值他们在堆中开辟的空间,若没有,则在常量池中开一个空间,并将其引用赋值给其在堆中开的空间,由于他们在堆中的地址是不同的,输出即为false。

------------------------------------------------------------------------------------------

【By the way】

【字符串常量池代码】

 public class BufferPoolDemo {
public static void main(String[] args) {
String s1="hello";
String s2="hello";
System.out.println(s1==s2);
}
}

【运行结果】

 true

【分析】

创建字符串的时候先查找字符串常量池中有没有相同的对象,如果有相同的对象就直接返回该对象的引用,如果没有相同的对象就在常量池中创建该对象,然后将该对象的引用返回。对于String s1=”hello”;这一步而言,常量池中没有hello这个字符串对象,所以首先创建一个字符串对象,然后将对象引用返回给s1。对于String s2=”hello”;这一步而言,缓冲池中有hello这个字符串对象,直接返回这个对象的引用给s2,此时,s1与s2公用一个字符串对象“hello”,所以s1与s2的内存地址是相同的,所以输出true。

----------------------------------------------------------------------------------------------------------------------------------------

【intern()方法的使用】

 public class BufferPoolDemo {
public static void main(String[] args) {
String s1=”hello”;
String s2=new String(“hello”);
s2=s2.intern();
System.out.println(s1==s2);
}
}

【运行结果】

 true

【分析】

先来说说intern()这个方法的作用吧,这个方法的作用是返回在字符串缓冲池中的对象的引用,所以s2指向的也是字符串缓冲池中的地址,和s1是相等的。

byte数据常量池问题的更多相关文章

  1. [一]class 文件浅析 .class文件格式详解 字段方法属性常量池字段 class文件属性表 数据类型 数据结构

    前言概述  本文旨在讲解class文件的整体结构信息,阅读本文后应该可以完整的了解class文件的格式以及各个部分的逻辑组成含义   class文件包含了java虚拟机指令集 和  符号表   以及若 ...

  2. java 多线程10:synchronized锁机制 之 锁定类静态方法 和锁定类.Class 和 数据String的常量池特性

    同步静态方法 synchronized还可以应用在静态方法上,如果这么写,则代表的是对当前.java文件对应的Class类加锁.看一下例子,注意一下printC()并不是一个静态方法: public ...

  3. java---堆、栈、常量池的存储数据

    说到Java中堆.栈和常量池,首先还是看看他们各自存放的数据类型吧! 栈: Java的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method)也叫静态存储区. 堆区:(存放所 ...

  4. Java中的字符串常量池和JVM运行时数据区的相关概念

    什么是字符串常量池 JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池 工作原理 当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量 ...

  5. Java堆、栈和常量池以及相关String的详细讲解(经典中的经典) (转)

    原文链接 : http://www.cnblogs.com/xiohao/p/4296088.html 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的 ...

  6. JVM常量池

    常量池(constant_pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据.它包括了关于类.方法.接口等中的常量,也包括字符串常量和符号引用.运行时常量池是方法区的一部分 ...

  7. Java堆、栈和常量池

    摘录自 http://www.cnblogs.com/xiohao/p/4296088.html 1. 栈(stack)与堆(heap)都是Java用来在RAM中存放数据的地方.与C++不同,Java ...

  8. Java堆、栈和常量池以及相关String的详细讲解

    一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...

  9. 【转载】Java常量池

    本篇随笔为转载,原贴地址:Java常量池理解与总结. (其实Java的常量池有点像C++中的存储字符串常量的常量存储区). 一.相关概念 什么是常量用final修饰的成员变量表示常量,值一旦给定就无法 ...

随机推荐

  1. python中的各种锁

    一.全局解释器锁(GIL) 1.什么是全局解释器锁 在同一个进程中只要有一个线程获取了全局解释器(cpu)的使用权限,那么其他的线程就必须等待该线程的全局解释器(cpu)使 用权消失后才能使用全局解释 ...

  2. vscode开发c#

    转载自: http://www.cnblogs.com/lxhbky/p/6673230.html http://www.cnblogs.com/lxhbky/p/6692065.html 一.环境安 ...

  3. 改造 Android 官方架构组件 ViewModel

    前言 Android 官方架构组件在今年 5 月份 Google I/O 大会上被公布, 直到 11 月份一直都是测试版, 由于工作比较繁忙, 期间我只是看过类似的文章, 但没有在实际项目中使用过, ...

  4. SQL Server 函数之日期格式化函数

    SQL Server 函数之日期格式化函数 高文龙关注0人评论612人阅读2017-09-23 13:47:07 SQL Server 函数之日期格式化函数 对于一些经常写SQL Server执行语句 ...

  5. Confluence 6 配置自动备份

    希望配置 Confluence 备份: 进入  > 基本配置(General Configuration) > 备份管理(Backup administration). 选择 编辑(Edi ...

  6. Java的实验程序之输出单个文件中的前 N 个最常出现的英语单词

    日期:2018.10.11 星期四 博客期:016 题目:输出单个文件中的前 N 个最常出现的英语单词,并输出到文本文件中 在程序运行之前,我试着先写了字符的字母的总结,加载代码如下: //如下是第一 ...

  7. PHP之十六个魔术方法

    1.__construct,__destruct__constuct构建对象的时被调用:__destruct明确销毁对象或脚本结束时被调用:2.__get,__set__set当给不可访问或不存在属性 ...

  8. LeetCode(125):验证回文串

    Easy! 题目描述: 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写. 说明:本题中,我们将空字符串定义为有效的回文串. 示例 1: 输入: "A man, ...

  9. java 命令行运行时报错:找不到或无法加载主类

    源码如下: 路径目录(...\src\object) //: ch1.10/Command.java /**@author feilong * @version 1.0 */ package obje ...

  10. Kali linux Nessus &Cracking Password

    1 .Nessus漏洞网站测试(真正体会到什么是专业版和社区版的区别,要技术就不光要勤恳的态度,严谨的思维.还有矢志不渝的志气,还必须要求砸钱,所以狠狠的赚钱才是硬道理),我的半个社区版的很多扫描模块 ...