程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Java你可能不知道的事系列(1),java系列

Java你可能不知道的事系列(1),java系列

編輯:JAVA綜合教程

Java你可能不知道的事系列(1),java系列


概述

本類文章會不段更新分析學習到的經典面試題目,在此記錄下來便於自己理解。如果有不對的地方還請各位觀眾拍磚。 
今天主要分享一下常用的字符串的幾個題目,相信學習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);

 

好了,今天就到這裡。之後會繼續分析。如果喜歡我的文章歡迎關注我。求贊,有問題可以評論,各位的支持是我最大的動力!!

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved