簡體   English   中英

Java字符串池和類型轉換

[英]Java String pool and type casting

我的問題是關於Java處理字符串文字的方式。 從Java語言規范(JLS)可以清楚地看出,字符串文字是隱式實現的 - 換句話說,就是在堆的String常量池部分中創建的對象,與調用new String("whatever")時創建的基於堆的對象形成對比。 new String("whatever")

似乎與JLS所說的不一致的是,當使用字符串連接創建一個新的String時,使用一個轉換的常量String類型,根據JLS應該將其視為一個常量String,顯然JVM正在創建一個新的String對象而不是隱式實現它。 我感謝有關此特定行為的任何解釋以及這是否是特定於平台的行為。 我在Mac OSX Snow Leopard上運行。

public class Test
{
    public static void main(String args[])
    {
        /*
            Create a String object on the String constant pool
            using a String literal
        */
        String hello = "hello";
        final String lo = "lo"; // this will be created in the String pool as well
        /*
            Compare the hello variable to a String constant expression
            , that should cause the JVM to implicitly call String.intern()
        */
        System.out.println(hello == ("hel" + lo));// This should print true
        /*
            Here we need to create a String by casting an Object back
            into a String, this will be used later to create a constant
            expression to be compared with the hello variable
        */
        Object object = "lo";
        final String stringObject = (String) object;// as per the JLS, casted String types can be used to form constant expressions
        /*
            Compare with the hello variable
        */
        System.out.println(hello == "hel" + stringObject);// This should print true, but it doesn't :(

    }
}

編譯時常量表達式中不允許強制轉換為Object 唯一允許的強制轉換是String和基元。 JLS(Java SE 7版)第15.28節:

> - 轉換為基本類型並轉換為String類型

(實際上還有第二個原因。 object不是final所以不能考慮一個常量變量 。“一個原始類型或類型String變量,是final ,用編譯時常量表達式(第15.28節)初始化,被稱為一個常數變量。“ - 第4.12.4節。)

似乎因為你在這里引用一個對象final String stringObject = (String) object; ,這不再是“編譯時”常量,而是“運行時”常量。 這里開始的第一個例子是:

String s = "lo";
String str7 = "Hel"+ s;  
String str8 = "He" + "llo"; 
System.out.println("str7 is computed at runtime.");     
System.out.println("str8 is created by using string constant expression.");    
System.out.println("    str7 == str8 is " + (str7 == str8));  
System.out.println("    str7.equals(str8) is " + str7.equals(str8));

字符串str7是在運行時計算的,因為它引用了另一個不是文字的字符串,所以通過該邏輯我假設盡管你使stringObject final,但它仍然引用一個對象,因此無法在編譯時計算。

這里的java語言規范來看,它指出:

“當結果不是編譯時常量表達式(第15.28節)時,字符串連接運算符+(第15.18.1節)隱式創建一個新的String對象。”

我找不到任何可以使用演員的例子,除了這個可怕的,可怕的例子:

System.out.println(hello == "hel" + ( String ) "lo");

這幾乎沒有任何合理用途,但由於上述情況,可能包括關於字符串強制轉換的部分。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM