精华内容
下载资源
问答
  • Java包装类常量池

    2020-10-12 20:52:02
    包装类 缓存对象 Byte -128~127 Short -128~127 Integer -128~127 Long -128~127 Float 没有 Double 没有 Character 0~127 Boolean true和false

    在这里插入图片描述

    包装类缓存对象
    Byte-128~127
    Short-128~127
    Integer-128~127
    Long-128~127
    Float没有
    Double没有
    Character0~127
    Booleantrue和false

    装箱与拆箱

    装箱:把基本数据类型转为包装类对象。

    转为包装类的对象,是为了使用专门为对象设计的API和特性

    拆箱:把包装类对象拆为基本数据类型。

    转为基本数据类型,一般是因为需要运算,Java中的大多数运算符是为基本数据类型设计的。比较、算术等

    基本数值---->包装对象

    Integer i1 = new Integer(4);//使用构造函数函数
    Integer i2 = Integer.valueOf(4);//使用包装类中的valueOf方法
    

    包装对象---->基本数值

    Integer i1 = new Integer(4);
    int num1 = i1.intValue();
    

    JDK1.5之后,可以自动装箱与拆箱。

    注意:只能与自己对应的类型之间才能实现自动装箱与拆箱。

     1. 包装类型与基本类型进行比较或者计算时会先自动拆箱,运算或者比较完后在自动装箱
    
    展开全文
  • /** * 8种基本类型的包装类和对象 * 包装类:java提供的为原始数据类型的封装类,如:int(基本数据类型),Integer封装类。...这5种整型的包装类的对象池范围在-128~127之间,也就是说, * 超出这
    /**
     * 8种基本类型的包装类和对象池
     * 		包装类:java提供的为原始数据类型的封装类,如:int(基本数据类型),Integer封装类。
     * 		对象池:为了一定程度上减少频繁创建对象,将一些对象保存到一个"容器"中。
     * 
     * 	Byte,Short,Integer,Long,Character。这5种整型的包装类的对象池范围在-128~127之间,也就是说,
     * 	超出这个范围的对象都会开辟自己的堆内存。
     * 
     *  Boolean也实现了对象池技术。Double,Float两种浮点数类型的包装类则没有实现。
     * 	String也实现了常量池技术。
     * 
     * 自动装箱拆箱技术
     * 	JDK5.0及之后允许直接将基本数据类型的数据直接赋值给其对应地包装类。
     *  如:Integer i = 3;(这就是自动装箱)
     *  实际编译代码是:Integer i=Integer.valueOf(3); 编译器自动转换
     * 	自动拆箱则与装箱相反:int i = (Integer)5;
     */
    
    public class Test {
    	public static void main(String[] args) {
    		
    		//基本数据类型常量池范围-128~127
    		Integer n1 = -129;
    		Integer n2 = -129;
    		Long n3 = 100L;
    		Long n4 = 100L;
    		Double n5 =  12.0;
    		Double n6 = 12.0;
    		//false
    		System.out.println(n1 == n2);
    		//true
    		System.out.println(n3 == n4);
    		//false
    		System.out.println(n5 == n6);
    		
    		//String常量池技术,注意:这里String不是用new创建的对象
    		String str1 = "abcd";
    		String str2 = "abcd";
    		//true
    		System.out.println(str1 == str2);
    	}
    }
    

    展开全文
  • Java包装类常量池

    2015-10-27 20:58:47
    Integer a=Integer.valueOf(100); Integer b=Integer.valueOf(100); System.out.println(a==b); Double d1=Double.valueOf(100); Double d2=Double.valueOf(100); System.out.println...为什么包装类 Inge...
    Integer a=Integer.valueOf(100);
    Integer b=Integer.valueOf(100);
    System.out.println(a==b);
    Double d1=Double.valueOf(100);
    Double d2=Double.valueOf(100);
    System.out.println(d1==d2); 
     
    为什么包装类 Ingeter两个值就相等 Double的就不相等了呢

     

    在给Integer赋值时,实际上是自动装箱的过程,也就是调用了Integer.valueOf(int)方法,当这个值大于等于-128并且小于等于127时使用了常量池,所以前两个地址是相等的,但是后两个超过了127,故不使用常量池。

    也就是说
    Integer -128~127实际上你可以看成是整形int,所以第一个类的输出结果应该是==
    Interger 128以上的数值就不能看成int了,他是对象,两个值相同的不同的对象如果用==判断肯定是不等的,可以用equals判断。

     Java的8种基本类型 (Byte, Short, Integer, Long, Character, Boolean, Float, Double), 除Float和 Double以外, 其它六种都实现了常量池, 但是它们只在大于等于-128并且小于等于127时才使用常量池。 

    Java包装类常量池详解  

     

    public class IntegerTest { 
            public static void main(String[] args) {     
                objPoolTest(); 
            } 
         
            public static void objPoolTest() { 
                Integer i1 = 40; 
                Integer i2 = 40; 
                Integer i3 = 0;

              

                Integer i4 = new Integer(40); 
                Integer i5 = new Integer(40); 
                Integer i6 = new Integer(0); 
                 Integer i7 = 140; 
                 Integer i8 = 140;
                System.out.println("i1=i2\t" + (i1 == i2)); 
                System.out.println("i1=i2+i3\t" + (i1 == i2 + i3)); 
                System.out.println("i4=i5\t" + (i4 == i5)); 
                System.out.println("i4=i5+i6\t" + (i4 == i5 + i6));     
                 System.out.println("i7=i8\t" + (i7 == i8);
                System.out.println();         
            } 
        }

    i1=i2 true
    i1=i2+i3 true
    i4=i5 false
    i4=i5+i6 true

    i7=i8 false

    Java为了提高性能提供了和String类一样的对象池机制,当然Java的八种基本类型的包装类(Packaging Type)也有对象池机制。

    Integer i1=40;Java在编译的时候会执行将代码封装成Integer i1=Integer.valueOf(40);通过查看Source Code发现:

    Integer.valueOf()中有个内部类IntegerCache(类似于一个常量数组,也叫对象池),它维护了一个Integer数组cache,长度为(128+127+1)=256,Integer类中还有一个Static Block(静态块)。

    从这个静态块可以看出,Integer已经默认创建了数值【-128-127】的Integer缓存数据。所以使用Integer i1=40时,JVM会直接在该在对象池找到该值的引用。也就是说这种方式声明一个Integer对象时,JVM首先会在Integer对象的缓存池中查 找有木有值为40的对象,如果有直接返回该对象的引用;如果没有,则使用New keyword创建一个对象,并返回该对象的引用地址。因为Java中【==】比较的是两个对象是否是同一个引用(即比较内存地址),i2和i2都是引用 的同一个对象,So i1==i2结果为”true“;而使用new方式创建的i4=new Integer(40)、i5=new Integer(40),虽然他们的值相等,但是每次都会重新Create新的Integer对象,不会被放入到对象池中,所以他们不是同一个引用,输出 false。

    对于i1==i2+i3、i4==i5+i6结果为True,是因为,Java的数学计算是在内存栈里操作的,Java会对i5、i6进行拆箱操作,其实比较的是基本类型(40=40+0),他们的值相同,因此结果为True。

    好了,我想说道这里大家应该都会对Integer对象池有了更进一步的了解了吧,我在诺诺的问一句如果把40改为400猜猜会输出什么?

    i1=i2false i1=i2+i3true i4=i5false i4=i5+i6true

    这是因为Integer i1=400,Integer i2=400他们的值已经超出了常量池的范围,JVM会对i1和i2各自创建新的对象(即Integer i1=new Integer(400)),所以他们不是同一个引用。

    展开全文
  • 字符串常量池、class常量池和运行时常量池

    万次阅读 多人点赞 2017-06-12 20:09:36
    在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着...

     

    原文链接:http://tangxman.github.io/2015/07/27/the-difference-of-java-string-pool/

                           

    在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着来区分一下这几个概念。

    1.全局字符串池(string pool也有叫做string literal pool)

    全局字符串池里的内容是在类加载完成,经过验证,准备阶段之后在堆中生成字符串对象实例,然后将该字符串对象实例的引用值存到string pool中记住:string pool中存的是引用值而不是具体的实例对象,具体的实例对象是在堆中开辟的一块空间存放的。)。 在HotSpot VM里实现的string pool功能的是一个StringTable类,它是一个哈希表,里面存的是驻留字符串(也就是我们常说的用双引号括起来的)的引用(而不是驻留字符串实例本身),也就是说在堆中的某些字符串实例被这个StringTable引用之后就等同被赋予了”驻留字符串”的身份。这个StringTable在每个HotSpot VM的实例只有一份,被所有的类共享。

    2.class文件常量池(class constant pool)

    我们都知道,class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池(constant pool table),用于存放编译器生成的各种字面量(Literal)和符号引用(Symbolic References)。 字面量就是我们所说的常量概念,如文本字符串、被声明为final的常量值等。 符号引用是一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可(它与直接引用区分一下,直接引用一般是指向方法区的本地指针,相对偏移量或是一个能间接定位到目标的句柄)。一般包括下面三类常量:

    • 类和接口的全限定名
    • 字段的名称和描述符
    • 方法的名称和描述符

    常量池的每一项常量都是一个表,一共有如下表所示的11种各不相同的表结构数据,这每个表开始的第一位都是一个字节的标志位(取值1-12),代表当前这个常量属于哪种常量类型。 常量池的项目类型每种不同类型的常量类型具有不同的结构,具体的结构本文就先不叙述了,本文着重区分这三个常量池的概念(读者若想深入了解每种常量类型的数据结构可以查看《深入理解java虚拟机》第六章的内容)。

    3.运行时常量池(runtime constant pool)

    java文件被编译成class文件之后,也就是会生成我上面所说的class常量池,那么运行时常量池又是什么时候产生的呢?

    jvm在执行某个类的时候,必须经过加载、连接、初始化,而连接又包括验证、准备、解析三个阶段。而当类加载到内存中后,jvm就会将class常量池中的内容存放到运行时常量池中,由此可知,运行时常量池也是每个类都有一个。在上面我也说了,class常量池中存的是字面量和符号引用,也就是说他们存的并不是对象的实例,而是对象的符号引用值。而经过解析(resolve)之后,也就是把符号引用替换为直接引用,解析的过程会去查询全局字符串池,也就是我们上面所说的StringTable,以保证运行时常量池所引用的字符串与全局字符串池中所引用的是一致的。

    举个实例来说明一下:

    public class HelloWorld {
        public static void main(String []args) {
    		String str1 = "abc"; 
    		String str2 = new String("def"); 
    		String str3 = "abc"; 
    		String str4 = str2.intern(); 
    		String str5 = "def"; 
    		System.out.println(str1 == str3);//true 
    		System.out.println(str2 == str4);//false 
    		System.out.println(str4 == str5);//true
        }
    }

    回到上面的那个程序,现在就很容易解释整个程序的内存分配过程了,首先,在堆中会有一个”abc”实例,全局StringTable中存放着”abc”的一个引用值,然后在运行第二句的时候会生成两个实例,一个是”def”的实例对象,并且StringTable中存储一个”def”的引用值,还有一个是new出来的一个”def”的实例对象,与上面那个是不同的实例,当在解析str3的时候查找StringTable,里面有”abc”的全局驻留字符串引用,所以str3的引用地址与之前的那个已存在的相同,str4是在运行的时候调用intern()函数,返回StringTable中”def”的引用值,如果没有就将str2的引用值添加进去,在这里,StringTable中已经有了”def”的引用值了,所以返回上面在new str2的时候添加到StringTable中的 “def”引用值,最后str5在解析的时候就也是指向存在于StringTable中的”def”的引用值,那么这样一分析之后,下面三个打印的值就容易理解了。上面程序的首先经过编译之后,在该类的class常量池中存放一些符号引用,然后类加载之后,将class常量池中存放的符号引用转存到运行时常量池中,然后经过验证,准备阶段之后,在堆中生成驻留字符串的实例对象(也就是上例中str1所指向的”abc”实例对象),然后将这个对象的引用存到全局String Pool中,也就是StringTable中,最后在解析阶段,要把运行时常量池中的符号引用替换成直接引用,那么就直接查询StringTable,保证StringTable里的引用值与运行时常量池中的引用值一致,大概整个过程就是这样了。

    总结

    • 1.全局常量池在每个VM中只有一份,存放的是字符串常量的引用值。
    • 2.class常量池是在编译的时候每个class都有的,在编译阶段,存放的是常量的符号引用。
    • 3.运行时常量池是在类加载完成之后,将每个class常量池中的符号引用值转存到运行时常量池中,也就是说,每个class都有一个运行时常量池,类在解析之后,将符号引用替换成直接引用,与全局常量池中的引用值保持一致。

     

    ================================

     

     

    class文件常量池和运行时常量池

    最近一直被方法区里面存着什么东西困扰着?

           1.方法区里存class文件信息和class文件常量池是个什么关系。

            2.class文件常量池和运行时常量池是什么关系。        

            方法区存着类的信息,常量和静态变量,即类被编译后的数据。这个说法其实是没问题的,只是太笼统了。更加详细一点的说法是方法区里存放着类的版本,字段,方法,接口和常量池。常量池里存储着字面量和符号引用。

           符号引用包括:1.类的全限定名,2.字段名和属性,3.方法名和属性。

           下面一张图是我画的方法区,class文件信息,class文件常量池和运行时常量池的关系

           

           下面一张图用来表示方法区class文件信息包括哪些内容:

           

             可以看到在方法区里的class文件信息包括:魔数,版本号,常量池,类,父类和接口数组,字段,方法等信息,其实类里面又包括字段和方法的信息。

             下面的图表是class文件中存储的数据类型             

     

    类型名称数量
    u4magic1
    u2minor_version1
    u2major_version1
    u2constant_pool_count1
    cp_infoconstant_poolconstant_pool_count - 1
    u2access_flags1
    u2this_class1
    u2super_class1
    u2interfaces_count1
    u2interfacesinterfaces_count
    u2fields_count1
    field_infofieldsfields_count
    u2methods_count1
    method_infomethodsmethods_count
    u2attribute_count1
    attribute_infoattributesattributes_count

     

           下面用一张图来表示常量池里存储的内容:

            这里写图片描述

     

    用一个class文件实际反编译一下

    下面是原java代码

     

    [java] view plain copy

    1. public class TestInt {    
    2.     private String str = "hello";    
    3.     void printInt(){    
    4.         System.out.println(65535);    
    5.     }    
    6. }   


    经过反编译后获得class文件是下面这样的

     

    可以看出被反编译的class文件中的内容和上面所说的是能对应上的。这就解答了class文件和class文件常量池的关系

    class文件常量池和运行时常量池的关系以及区别

    class文件常量池存储的是当class文件被java虚拟机加载进来后存放在方法区的一些字面量和符号引用,字面量包括字符串,基本类型的常量。

    运行时常量池是当class文件被加载完成后,java虚拟机会将class文件常量池里的内容转移到运行时常量池里,在class文件常量池的符号引用有一部分是会被转变为直接引用的,比如说类的静态方法或私有方法,实例构造方法,父类方法,这是因为这些方法不能被重写其他版本,所以能在加载的时候就可以将符号引用转变为直接引用,而其他的一些方法是在这个方法被第一次调用的时候才会将符号引用转变为直接引用的。

    总结:

    方法区里存储着class文件的信息和运行时常量池,class文件的信息包括类信息和class文件常量池。

    运行时常量池里的内容除了是class文件常量池里的内容外,还将class文件常量池里的符号引用转变为直接引用,而且运行时常量池里的内容是能动态添加的。例如调用String的intern方法就能将string的值添加到String常量池中,这里String常量池是包含在运行时常量池里的,但在jdk1.8后,将String常量池放到了堆中。

    下面有一篇文章写的是比较好的

    http://blog.csdn.net/vegetable_bird_001/article/details/51278339
     

    https://www.cnblogs.com/holos/p/6603379.html

    =====================================

    基本类型的包装类、String类和常量池

     

    一.相关概念


    1. 什么是常量
      用final修饰的成员变量表示常量,值一旦给定就无法改变!
      final修饰的变量有三种:静态变量、实例变量和局部变量,分别表示三种类型的常量。

    2. Class文件中的常量池
      在Class文件结构中,最头的4个字节用于存储魔数Magic Number,用于确定一个文件是否能被JVM接受,再接着4个字节用于存储版本号,前2个字节存储次版本号,后2个存储主版本号,再接着是用于存放常量的常量池,由于常量的数量是不固定的,所以常量池的入口放置一个U2类型的数据(constant_pool_count)存储常量池容量计数值。
      常量池主要用于存放两大类常量:字面量(Literal)和符号引用量(Symbolic References),字面量相当于Java语言层面常量的概念,如文本字符串,声明为final的常量值等,符号引用则属于编译原理方面的概念,包括了如下三种类型的常量:

    • 类和接口的全限定名
    • 字段名称和描述符
    • 方法名称和描述符
    1. 方法区中的运行时常量池
      运行时常量池是方法区的一部分。
      CLass文件中除了有类的版本、字段、方法、接口等描述信息外,还有一项信息是常量池,用于存放编译期生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
      运行时常量池相对于CLass文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入CLass文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的就是String类的intern()方法。

    2. 常量池的好处
      常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。
      例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。
      (1)节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。
      (2)节省运行时间:比较字符串时,==比equals()快。对于两个引用变量,只用==判断引用是否相等,也就可以判断实际值是否相等。

    3. 双等号==的含义
      基本数据类型之间应用双等号,比较的是他们的数值。
      复合数据类型(类)之间应用双等号,比较的是他们在内存中的存放地址。

    二.8种基本类型的包装类和常量池


    1. java中基本类型的包装类的大部分都实现了常量池技术,
      即Byte,Short,Integer,Long,Character,Boolean;
    
      Integer i1 = 40;
      Integer i2 = 40;
      System.out.println(i1==i2);//输出TRUE
    

    这5种包装类默认创建了数值[-128,127]的相应类型的缓存数据,但是超出此范围仍然会去创建新的对象。

    
    //Integer 缓存代码 :
    public static Integer valueOf(int i) {
            assert IntegerCache.high >= 127;
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }
    
    
      Integer i1 = 400;
      Integer i2 = 400;
      System.out.println(i1==i2);//输出false
    
    1. 两种浮点数类型的包装类Float,Double并没有实现常量池技术。
    
       Double i1=1.2;
       Double i2=1.2;
       System.out.println(i1==i2);//输出false
    
    1. 应用常量池的场景
      (1)Integer i1=40;Java在编译的时候会直接将代码封装成Integer i1=Integer.valueOf(40);,从而使用常量池中的对象。
      (2)Integer i1 = new Integer(40);这种情况下会创建新的对象。
    
      Integer i1 = 40;
      Integer i2 = new Integer(40);
      System.out.println(i1==i2);//输出false
    
    1. Integer比较更丰富的一个例子
    
      Integer i1 = 40;
      Integer i2 = 40;
      Integer i3 = 0;
      Integer i4 = new Integer(40);
      Integer i5 = new Integer(40);
      Integer i6 = new Integer(0);
      
      System.out.println("i1=i2   " + (i1 == i2));
      System.out.println("i1=i2+i3   " + (i1 == i2 + i3));
      System.out.println("i1=i4   " + (i1 == i4));
      System.out.println("i4=i5   " + (i4 == i5));
      System.out.println("i4=i5+i6   " + (i4 == i5 + i6));   
      System.out.println("40=i5+i6   " + (40 == i5 + i6));     
    
    
    i1=i2   true
    i1=i2+i3   true
    i1=i4   false
    i4=i5   false
    i4=i5+i6   true
    40=i5+i6   true
    

    解释:语句i4 == i5 + i6,因为+这个操作符不适用于Integer对象,首先i5和i6进行自动拆箱操作,进行数值相加,即i4 == 40。然后Integer对象无法与数值进行直接比较,所以i4自动拆箱转为int值40,最终这条语句转为40 == 40进行数值比较。
    Java中的自动装箱与拆箱

     

    三.String类和常量池


    1. String对象创建方式
    
         String str1 = "abcd";
         String str2 = new String("abcd");
         System.out.println(str1==str2);//false
    

    这两种不同的创建方法是有差别的,第一种方式是在常量池中拿对象,第二种方式是直接在堆内存空间创建一个新的对象。
    只要使用new方法,便需要创建新的对象。

    1. 连接表达式 +
      (1)只有使用引号包含文本的方式创建的String对象之间使用“+”连接产生的新对象才会被加入字符串池中。
      (2)对于所有包含new方式新建对象(包括null)的“+”连接表达式,它所产生的新对象都不会被加入字符串池中。
    
      String str1 = "str";
      String str2 = "ing";
      
      String str3 = "str" + "ing";
      String str4 = str1 + str2;
      System.out.println(str3 == str4);//false
      
      String str5 = "string";
      System.out.println(str3 == str5);//true
    

    java基础:字符串的拼接

    • 特例1
    
    public static final String A = "ab"; // 常量A
    public static final String B = "cd"; // 常量B
    public static void main(String[] args) {
         String s = A + B;  // 将两个常量用+连接对s进行初始化 
         String t = "abcd";   
        if (s == t) {   
             System.out.println("s等于t,它们是同一个对象");   
         } else {   
             System.out.println("s不等于t,它们不是同一个对象");   
         }   
     } 
    s等于t,它们是同一个对象
    

    A和B都是常量,值是固定的,因此s的值也是固定的,它在类被编译时就已经确定了。也就是说:String s=A+B; 等同于:String s="ab"+"cd";

    • 特例2
    
    public static final String A; // 常量A
    public static final String B;    // 常量B
    static {   
         A = "ab";   
         B = "cd";   
     }   
     public static void main(String[] args) {   
        // 将两个常量用+连接对s进行初始化   
         String s = A + B;   
         String t = "abcd";   
        if (s == t) {   
             System.out.println("s等于t,它们是同一个对象");   
         } else {   
             System.out.println("s不等于t,它们不是同一个对象");   
         }   
     } 
    s不等于t,它们不是同一个对象
    

    A和B虽然被定义为常量,但是它们都没有马上被赋值。在运算出s的值之前,他们何时被赋值,以及被赋予什么样的值,都是个变数。因此A和B在被赋值之前,性质类似于一个变量。那么s就不能在编译期被确定,而只能在运行时被创建了。

    1. String s1 = new String("xyz"); 创建了几个对象? 
      考虑类加载阶段和实际执行时。
      (1)类加载对一个类只会进行一次。"xyz"在类加载时就已经创建并驻留了(如果该类被加载之前已经有"xyz"字符串被驻留过则不需要重复创建用于驻留的"xyz"实例)。驻留的字符串是放在全局共享的字符串常量池中的。
      (2)在这段代码后续被运行的时候,"xyz"字面量对应的String实例已经固定了,不会再被重复创建。所以这段代码将常量池中的对象复制一份放到heap中,并且把heap中的这个对象的引用交给s1 持有。
      这条语句创建了2个对象。

    2. java.lang.String.intern()
      运行时常量池相对于CLass文件常量池的另外一个重要特征是具备动态性,Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入CLass文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,这种特性被开发人员利用比较多的就是String类的intern()方法。
      String的intern()方法会查找在常量池中是否存在一份equal相等的字符串,如果有则返回该字符串的引用,如果没有则添加自己的字符串进入常量池。

    
    public static void main(String[] args) {    
          String s1 = new String("计算机");
          String s2 = s1.intern();
          String s3 = "计算机";
          System.out.println("s1 == s2? " + (s1 == s2));
          System.out.println("s3 == s2? " + (s3 == s2));
      }
    
    
    s1 == s2? false
    s3 == s2? true
    
    1. 字符串比较更丰富的一个例子
    
    public class Test {
     public static void main(String[] args) {   
          String hello = "Hello", lo = "lo";
          System.out.println((hello == "Hello") + " ");
          System.out.println((Other.hello == hello) + " ");
          System.out.println((other.Other.hello == hello) + " ");
          System.out.println((hello == ("Hel"+"lo")) + " ");
          System.out.println((hello == ("Hel"+lo)) + " ");
          System.out.println(hello == ("Hel"+lo).intern());
     }   
    }
    class Other { static String hello = "Hello"; }
    package other;
    public class Other { public static String hello = "Hello"; }
    
    
    true true true true false true```
    在同包同类下,引用自同一String对象.
    在同包不同类下,引用自同一String对象.
    在不同包不同类下,依然引用自同一String对象.
    在编译成.class时能够识别为同一字符串的,自动优化成常量,引用自同一String对象.
    在运行时创建的字符串具有独立的内存地址,所以不引用自同一String对象.
    
    
    -----
    [2015-08-26]



    作者:梦工厂
    链接:https://www.jianshu.com/p/c7f47de2ee80
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

     

    展开全文
  • Java基本数据类型与包装类的区别(栈、堆、常量池) 基本数据类型 基本数据类型(原始数据类型):包括八种基本数据类型: 基本数据类型(全部小写) 取值范围 所占字节长度 boolean true/false 理论上占用1bit,...
  • 一、什么是包装类 java中的数据类型int,double等不是对象,无法通过向上转型...例如做一些进制转换,获取int数据类型的取值范围等等。 我们知道,类的优点在于,它可以定义成员变量、成员方法,提供丰富便利的功能。
  • 在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着来区分...
  • java包装类常量池

    2015-08-05 13:14:23
    8个基本类型对应的包装类,都引入了常量池的概念。范围是-128-127。详见源码。
  • 在java的内存分配中,经常听到很多关于常量池的描述,我开始看的时候也是看的很模糊,网上五花八门的说法简直太多了,最后查阅各种资料,终于算是差不多理清了,很多网上说法都有问题,笔者尝试着来区分一下这几个...
  • 在java中有三中对字符串的操作方式。 注:文章只注明思路原理。...1、String 常量 效率较低 指的是多进行字符串拼接操作时的效率 final 2、StringBuffer 变量 效率其次 多线程安全 3、StringBuilder 变...
  • 1.重写Object的方法。 toString方法,原本的toString方法是Object提供的,用于打印hashCode,重写的目的是用于打印当前对象的属性和值。 2.equals方法, 原本的equals方法是Object提供的,用于比较两个对象的...
  • 为什么要有常量池常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。 例如字符串常量池,在编译阶段就把所有的字符串文字放到一个常量池中。...基本数据类型的包装类常量池...
  • 常量池(1) 首先看看下面这段代码,猜猜输出结果是什么? public static void main(String[] args) { Integer n1= 127; Integer n2 = 127; System.out.println(n1==n2); Integer n3 = 128; Integer ...
  • 基本数据类型与常量池

    千次阅读 2018-07-17 21:49:30
     java虚拟机缓存了Integer、Byte、Short、Character、Boolean包装类在-128~127之间的值,如果取值在这个范围内,会从int常量池取出一个int并自动装箱成Integer,超出这个范围就会重新创建一个。 转载: ...
  • 什么是常量? 用 final 修饰的成员变量表示常量,值一旦给定就无法改变! final 修饰的变量有三种,分别表示三种类型的常量。 静态变量 实例变量 局部变量 ...一、三种常量池描述 ...三、方法区和常量池(cl
  • Byte ,Short ,Integer ,Long ,Character的对象池(常量池)的取值范围是-128到正的127,当超过这个范围的对象会开辟自己的堆内存,Boolean也实现了对象池技术,Double和Float这两种浮点类型的包装类没有实现这个...
  • 关于引用类型,常量池包装类缓存等问题小结
  • Java面试题大全(2020版)

    万次阅读 多人点赞 2019-11-26 11:59:06
    String str="i"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String("i") 则会被分到堆内存中。 9. 如何将字符串反转? 使用 StringBuilder 或者 stringBuffer 的 reverse() 方法。 示例代码: // ...
  • 字符串常量池及byte数据常量池

    千次阅读 2017-03-13 17:03:27
    Byte型数据缓冲Demo1public class BufferPoolDemo { public static void main(String[] args) { Integer i1=127; Integer i2=127; System.out.println(i1==i2); System.out.println
  • java中的常量池

    2019-08-30 12:37:40
    在java中,JVM会为String类和几个基本数据类型(Integer、Byte、Short、Character、Boolean)的包装类创建常量池常量池会事先创建多个对象存储在池中,如果你想要创建的对象符合条件,会直接从常量池中获取,而不是...
  • 常量池 (constant pool) 堆与栈 字符串内存分配 基础类型的变量和常量在内存中的分配 成员变量和局部变量在内存中的分配 寄存器:最快的存储区,位于不同于其他存储区的地方——处理器内部。寄存器的数量极其...
  • 而第二种是先在栈中创建一个对 String的对象引用变量str,然后通过符号引用去字符串常量池 里找有没有"abc",如果没有,则将"abc"存放进字符串常量池 ,并令str指向”abc”,如果已经有”abc” 则直接令str指向...
  • 聊聊Java的常量池

    2018-12-28 14:42:00
    Java中的常量池,实际上分为两种形态:静态...JVM虚拟机在完成装载操作后,将class文件中的常量池载入到内存中,并保存在方法区中,我们常说的常量池,就是指方法区中的运行时常量池。 网络上流行的常量池例子 ...
  • 如果敌人让你生气,那说明你还没有胜他的把握,如果朋友让你生气,那说明你仍然在意他的友情 java内存的基本概念 ...进程所创建的所有的实例(也就是对象)或数组(指的是数组的本身,不是引用)...
  • Java堆栈常量池深入

    2017-10-25 22:36:40
    2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)  3. 堆:存放所有new出来的对象。  4. 静态域:存放...
  • 文章目录一、前言二、String 类和常量池问题一:问题二:问题三:问题四:问题五:问题六:问题七:问题八:三、8种基本类型的包装类常量池四、 一、前言 二、String 类和常量池 黄金三句: 1、直接使用双引号...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,167
精华内容 2,066
关键字:

包装类常量池取值范围