我来自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
期望以后会出现什么问题:
BufferedWriter
String
Writer
课程中的System.out.print()
。对于期望的结果会有任何含糊之处吗?
在类似的(根据我的看法)PrintStream
中System.out.println(l1); // <- this works fine
完美无瑕地工作:
PrintStream
println(Long)
也不包含long
方法。这是否意味着它首先转换为out.print(long)
,然后使用此方法(BufferedWriter
),因此在{{1}}的情况下无法完成此步骤?
答案 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.html和print(Object)
。 Java可以在使用http://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.html
和println(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)
我似乎很清楚(根据评论)并查看Writer
类Writer
类只应该写单个字符。因此要求它打印一个整数值(无论是长整数,字节,短整数还是其他整数)都违背了该类的意图(对于一般对象也是如此)。是的,您可以传递一个整数值,但该值实际一个char
- 不一个int
- 所以它会打印char
值而不是int
值。
l1 + ","
工作的事实是因为编译器将其转换为String
对象(Writer
然后转换为char数组并写入String
值{ {1}} char
}。请注意,调用char
会产生“意外”结果。)
如果要打印字符串表示,则应将Writer.write((int)(l1 + ','))
包裹在PrintWriter
内,即:
BufferedWriter
我还应该指出,如果你想非常小心,那么你应该使用OutputStreamWriter
并指定字符编码或字符集(这对阅读来说可能更重要)文件而不是写入文件,即你应该使用InputStreamReader
来阅读文本文件。)