簡體   English   中英

為什么BufferedWriter write()方法沒有自動廣播到String

[英]Why BufferedWriter write() method does not autocast to String

我來到了Java的這種行為,對我來說似乎有點奇怪。

在檢查這篇文章時,我確實意識到BufferedWriterwrite()方法不適用於Long對象:

BufferedWriter writer = new BufferedWriter(new FileWriter(outFile));
Long l1 = new Long(1);
writer.write(l1); // <- this won't work as it is

雖然我經常使用BufferedWriter ,但它的格式可以使用分隔符寫入多個值:

writer.write(l1 + ","); //<- this works fine.

因此,我猜想起區別的部分是+ ","部分,它實際上將l1.toString() + ","提供給BufferedWriter作為輸入。

我的問題是為什么Java在這些情況下不將自動廣播應用於String 我的意思是,既然write()期望出現什么問題:

  1. BufferedWriter實現的方法中的int
  2. 或字符數組
  3. Writer類中的String

預期結果是否會有歧義?

在類似的(根據我的看法System.out.print()PrintStream System.out.print()可以完美地工作:

System.out.println(l1); // <- this works fine

PrintStream也不包含println(Long)方法。 這是否意味着首先將其轉換為long ,然后使用此方法( out.print(long) ),所以對於BufferedWriter而言,此步驟無法完成?

在Java中,沒有“自動廣播到String ”這樣的東西。 當在字符串上下文中使用“ + ”運算符時,操作數將轉換為字符串。 這意味着您要查找的隱式轉換僅在“ + ”運算符的上下文中發生。

WriterBufferedWriter中可用的write()方法為:

  • void write(char[] cbuf) -寫入一個字符數組。
  • void write(char[] cbuf, int off, int len) -寫入字符數組的一部分。
  • void write(int c) -寫一個字符。
  • void write(String str) -寫入一個字符串。
  • void write(String str, int off, int len) -寫入字符串的一部分。

如果您想編寫其他內容,則將無法正常工作,因為write()方法不會因您要查找的變量而超載。

您正在尋找的是這樣的:

  • void print(Object o) -編寫一個對象,通過調用其toString()方法將其轉換為字符串,除非o == null ,在這種情況下將寫入字符串"null"

您可以使用包含此類方法的PrintWriter包裝BufferedWriter 尋找名為print而不是write 您會看到PrintWriter (就此而言, PrintStream )包含許多針對各種類型的重載方法,以便從字面上可以打印任何內容,而不僅僅是Stringchar acters。

因此,您的代碼如下所示:

PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(outFile)));
Long l1 = new Long(1);
writer.print(l1); // <- this works.

PS: PrintStreamPrintWriter包含兩種可以使用的方法: println(long) / print(long)println(Object) / print(Object) 請參閱http://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.htmlhttp://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.html Java可以在使用println(Object)println(long)之間“選擇”。 如果兩者均可用,則Java使用println(Object) ,如果我們對此稍作考慮,則很清楚原因。 long具有2 ^ 32個可能的值,但是Long (從邏輯角度來看)具有2 ^ 32 + 1個可能的值,因為它也可能為null 如果我們用null調用println(long) ,則會得到NullPointerException因為(Long) null無法成功拆箱到long 但是println(Object)可以使用null 將諸如long類的原始類型隱式轉換為諸如Long類的對應對象的過程稱為自動裝箱,相反過程稱為取消裝箱。 如果有選擇,編譯器將避免拆箱。

PPS:在Java中, 重載意味着一個類或對象提供多個具有相同名稱但具有不同參數類型列表的方法。 編譯器通過將參數類型與候選方法的參數類型進行匹配來選擇正確的方法。 可能構造不明確的案例,即writer.write(null) 可以使用強制類型轉換或變量, writer.write((String) null)String s = null; writer.write(s);來解決歧義String s = null; writer.write(s); String s = null; writer.write(s);

Long l1 = new Long(1);
writer.write(l1.toString()); //-> It is possible

writer.write(l1 + ",");  // here you concat the long with String it returns String

長+字符串->字符串。

BufferedWriter類沒有任何寫入Long的方法。

可能的寫入方法BufferedWriter

查看Java語言規范的第5.4節“字符串上下文” 它明確指出,“ + ”運算符在與字符串和其他對象一起使用時,將對那些其他非字符串對象使用字符串強制。

在我看來(基於評論)並且在Writer類看來, Writer應編寫單個字符,這似乎很清楚。 因此,要求它打印一個整數值(長,字節,短還是其他)與該類的意圖背道而馳(通用對象也是如此)。 是的,您可以為它傳遞一個整數值,但該值實際上是一個char 而不是 int因此它將打印char值而不是int值。

這一事實l1 + ","的工作原理是,因為編譯器轉換這對一個String對象(其Writer然后轉換成字符數組和寫入Stringchar通過char )。 請注意,調用Writer.write((int)(l1 + ','))將產生“意外”結果)。

如果要打印字符串表示形式,則應將BufferedWriter包裝在PrintWriter ,即:

public static PrintWriter getPrintWriter(final BufferedWriter bw){
    return new PrintWriter(bw);
}

我還應該指出,如果您要非常小心,則應使用OutputStreamWriter並指定字符編碼或字符集(這實際上對於讀取文件而不是寫入文件更重要,即應使用InputStreamReader進行讀取。文本文件)。

暫無
暫無

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

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