zoukankan      html  css  js  c++  java
  • Java你可能不知道的事系列1

    概述

    本类文章会不段更新分析学习到的经典面试题目,在此记录下来便于自己理解。如果有不对的地方还请各位观众拍砖。
    今天主要分享一下常用的字符串的几个题目,相信学习java的小伙伴们对String类是再熟悉不过了,今天我们就来和她再次邂逅,好了下面开始。

    先来说说String特点

    String是不可变的常量,每当我们创建一个字符串对象的时候,如果堆区的常量池里不存在这个字符串,就会创建一个存储在常量池里(String存的地方叫String pool),如果存在了,就直接把变量的地址指向常量池里,比如:String b = “abc” 这句话 内存表示如下。下面开始上题
    这里写图片描述

    1.1

    String s1 = new String("abc");
    String s2 = new String("abc"); 
    System.out.println(s1 == s2);

    输出结果是什么呢?
    从上面的图也大概说了jvm里面有栈区、堆区。栈区里面主要存放的是局部变量,堆区里存放的是new出来的对象。==对于对象类型比较的是地址。所以在s1和s1是分别引用了堆里面new出来的不同对象的地址,图形理解如下

    这里写图片描述

    答案很明显了,地址不同 输出false.

    1.2

    String s1 = "abc";
    StringBuffer s2 = new StringBuffer(s1); 
    System.out.println(s1.equals(s2));

    这是true 还是false呢?答案是false。

    首先s1变量引用了字符串”abc”,然后StringBuffer s2 = new StringBuffer(s1),新建了一个StringBuffer对象调用append()方法返回自身。调用String的equals方法。重点就是这个equals方法里有个instance of,必需是同一类型的才进行比较否则直接返回false。
    来看一下源码:

    /**
         * Compares this string to the specified object.  The result is {@code
         * true} if and only if the argument is not {@code null} and is a {@code
         * String} object that represents the same sequence of characters as this
         * object.
         *
         * @param  anObject
         *         The object to compare this {@code String} against
         *
         * @return  {@code true} if the given object represents a {@code String}
         *          equivalent to this string, {@code false} otherwise
         *
         * @see  #compareTo(String)
         * @see  #equalsIgnoreCase(String)
         */
        public boolean equals(Object anObject) {
            if (this == anObject) {
                return true;
            }
            //关键点就在这里了
            if (anObject instanceof String) {
                String anotherString = (String) anObject;
                int n = value.length;
                if (n == anotherString.value.length) {
                    char v1[] = value;
                    char v2[] = anotherString.value;
                    int i = 0;
                    while (n-- != 0) {
                        if (v1[i] != v2[i])
                                return false;
                        i++;
                    }
                    return true;
                }
            }
            return false;
        }

    1.3

    下面的代码在内存会产生几个对象呢?
    String s1 = new String(“abc”);
    String s2 = new String(“abc”);

    答案:3个
    有了上面的分析,相信大家都明白了,new了两个对象,加上string pool里的一个”abc”。

    1.4

    下面的代码输出结果是啥?

    String s1 = "abc";
    String s2 = new String("abc");
    s2.intern();
    System.out.println(s1 ==s2);

    我们可能对intern()这个方法不太熟悉,先来看看注释:

    /**
         * Returns a canonical representation for the string object.
         * <p>
         * A pool of strings, initially empty, is maintained privately by the
         * class <code>String</code>.
         * <p>
         * When the intern method is invoked, if the pool already contains a
         * string equal to this <code>String</code> object as determined by
         * the {@link #equals(Object)} method, then the string from the pool is
         * returned. Otherwise, this <code>String</code> object is added to the
         * pool and a reference to this <code>String</code> object is returned.
         * <p>
         * It follows that for any two strings <code>s</code> and <code>t</code>,
         * <code>s.intern()&nbsp;==&nbsp;t.intern()</code> is <code>true</code>
         * if and only if <code>s.equals(t)</code> is <code>true</code>.
         * <p>
         * All literal strings and string-valued constant expressions are
         * interned. String literals are defined in section 3.10.5 of the
         * <cite>The Java&trade; Language Specification</cite>.
         *
         * @return  a string that has the same contents as this string, but is
         *          guaranteed to be from a pool of unique strings.
         */
        public native String intern();

    注释好多我草,关键的是这句:When the intern method is invoked, if the pool already contains a string equal to this String object as determined by
    the {@link #equals(Object)} method, then the string from the pool is
    returned. Otherwise, this String object is added to the
    pool and a reference to this String object is returned.
    大致就是说,如果常量池里不存在这个字符串,就创建一个并且返回地址,否则的话直接返回地址。

    上面的代码第二行String s2 = new String(“abc”); s2其实是引用到了new的对象,虽然在第三行调用了intern方法,但是没有赋值给s2,所以s2的引用还是没有变。所以返回false。
    如果第三行代码改成s2 = s2.intern()就会返回true了。

     String s1 = "abc";
     String s2 = new String("abc");
     s2 = s2.intern();
     System.out.println(s1==s2);

    好了,今天就到这里。之后会继续分析。如果喜欢我的文章欢迎关注我。各位看官大爷的支持是我最大的动力!!

  • 相关阅读:
    5. JVM虚拟机栈
    4. 程序计数器
    3. JVM运行时数据区
    2. 类加载
    1. JVM体系结构
    SpringCloud 网关组件Gateway
    SpringCloud Hystrix断路器的基本使用
    SpringCloud Ribbon和Feign 的使用和源码分析
    反向代理的概念
    事务mysql
  • 原文地址:https://www.cnblogs.com/yangqiangyu/p/5383871.html
Copyright © 2011-2022 走看看