为什么BufferedWriter write()方法不会自动转发给String

时间:2014-12-17 08:33:01

标签: java

我来自java的这种行为对我来说似乎有点奇怪。

在我查看post时,我确实发现write() BufferedWriter方法不适用于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的输入之前虚拟调用String

我的问题是为什么java不对这些情况应用write()的自动播放。我的意思是自int期望以后会出现什么问题:

  1. BufferedWriter
  2. 中实施的方法中的String
  3. 或一组字符
  4. Writer课程中的System.out.print()
  5. 对于期望的结果会有任何含糊之处吗?

    在类似的(根据我的看法)PrintStreamSystem.out.println(l1); // <- this works fine 完美无瑕地工作:

    PrintStream

    println(Long)也不包含long方法。这是否意味着它首先转换为out.print(long),然后使用此方法(BufferedWriter),因此在{{1}}的情况下无法完成此步骤?

4 个答案:

答案 0 :(得分:2)

在Java中没有“自动转换为String”这样的东西。有什么是在String上下文中使用“+”运算符时,操作数将转换为字符串。这意味着您正在寻找的隐式转换只发生在“+” - 运算符的上下文中。

write()中的可用Writer方法因此BufferedWriter为:

  • 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"。 / LI>

您可以使用包含此类方法的BufferedWriter包裹PrintWriter;寻找名为print而不是write的方法。您可以看到PrintWriter(并且就此而言,PrintStream)包含许多针对各种类型的重载方法,因此几乎可以打印任何内容,而不仅仅是String和{{1 }} acters。

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

char

P.S .: PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(outFile))); Long l1 = new Long(1); writer.print(l1); // <- this works. 以及PrintStream包含两种可以使用的方法:PrintWriter / println(long)print(long) / println(Object)。请参阅http://docs.oracle.com/javase/8/docs/api/java/io/PrintStream.htmlprint(Object)。 Java可以在使用http://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.htmlprintln(Object)之间“选择”。如果两者都可用,Java使用println(long),如果我们稍微考虑一下,那么很清楚原因。 println(Object)有2 ^ 32个可能的值,但long(从逻辑角度看)有2 ^ 32 + 1个可能的值,因为它可能也是Long。如果我们使用null致电println(long),我们会null,因为NullPointerException无法成功取消装入(Long) null。但long可以与println(Object)一起使用。将null等基本类型隐式转换为像long这样的对象的过程称为自动装箱,反向过程称为拆箱。如果给出了选择,编译器就会避免拆箱。

P.P.S .: 在Java中,重载意味着类或对象提供多个具有相同名称但具有不同参数类型列表的方法。编译器通过将参数类型与候选方法的参数类型进行匹配来选择正确的方法。可以构造不明确的案例,即Long。可以使用强制转换或变量writer.write(null)writer.write((String) null)来解决歧义。

答案 1 :(得分:0)

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

长+字符串 - &gt;字符串。

BufferedWriter类没有任何写Long的方法。

可能的写入方法BufferedWriter

答案 2 :(得分:0)

看看the java language specification, section 5.4 "String context"。它明确指出“+”运算符与字符串和其他对象一起使用时,会对其他非字符串对象使用字符串强制。

答案 3 :(得分:0)

我似乎很清楚(根据评论)并查看WriterWriter应该写单个字符。因此要求它打印一个整数值(无论是长整数,字节,短整数还是其他整数)都违背了该类的意图(对于一般对象也是如此)。是的,您可以传递一个整数值,但该值实际一个char - 一个int - 所以它会打印char值而不是int值。

l1 + ","工作的事实是因为编译器将其转换为String对象(Writer然后转换为char数组并写入String值{ {1}} char}。请注意,调用char会产生“意外”结果。)

如果要打印字符串表示,则应将Writer.write((int)(l1 + ','))包裹在PrintWriter内,即:

BufferedWriter

我还应该指出,如果你想非常小心,那么你应该使用OutputStreamWriter并指定字符编码或字符集(这对阅读来说可能更重要)文件而不是写入文件,即你应该使用InputStreamReader来阅读文本文件。)