Java你可能不知道的事系列1

来源:互联网 发布:武汉ui培训知乎 编辑:程序博客网 时间:2024/05/29 03:20

概述

本类文章会不段更新分析学习到的经典面试题目,在此记录下来便于自己理解。如果有不对的地方还请各位观众拍砖。
今天主要分享一下常用的字符串的几个题目,相信学习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);

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

4 1