两个println输出java+12+34,和12+34+java
结果如下
具体打印的步骤能不能细讲一下
前者是字符串,所以后面的会转换成字符串,相连,输出java1246
后者,前面是数字,会先相加,再连接字符串,输出58java
这是由Java的字符串拼接顺序导致的。
因为,在第一个语句中,首先拼接 "java" 和 12,得到 "java12",然后再拼接 46,最终结果是 "java1246"。
在第二个语句中,首先拼接 12 和 46,得到 1246,然后再拼接 "java",最终结果是 "1246java"。
所以字符串的拼接顺序会影响最终结果。如果在拼接中出现数字,由于数字的运算优先级高于字符串,数字会首先相加,再与字符串拼接。而使用字符串格式化方式concatenation:
String s = "java";
String result = s + 12 + 46;
String result2 = 12 + 46 + s;
这样结果总是相同的:"java1246",因为字符串的拼接总是从左至右进行的。
(1)在涉及使用Context时,对于生命周期比Activity长的对象应该使用Application的Context。凡是使用Context优先考虑Application的Context,当然它并不是万能的,对于有些地方则必须使用Activity的Context。
(2)对于需要在静态内部类中使用非静态外部成员变量(如:Context、View ),可以在静态内部类中使用弱引用来引用外部类的变量来避免内存泄漏。
(3)对于不再需要使用的对象,显示的将其赋值为null,比如使用完Bitmap后先调用recycle(),再赋为null。
(4)保持对对象生命周期的敏感,特别注意单例、静态对象、全局性集合等的生命周期。
(5)对于生命周期比Activity长的内部类对象,并且内部类中使用了外部类的成员变量,可以这样做避免内存泄漏:1)将内部类改为静态内部类、2)静态内部类中使用弱引用来引用外部类的成员变量
根据参考资料中的源代码分析,可以解释为什么使用System.out.print()
在logcat中看不到日志,而使用System.out.println()
则可以看到日志。
先解释打印的步骤:
当调用System.out.print()
或System.out.println()
时,实际上是在调用PrintStream
中的相应方法。
在PrintStream
中的print(String s)
方法中,会调用write(String s)
方法,该方法用于将字符串写入输出流。
在write(String s)
方法中,首先会确保输出流是打开状态,然后获取字符输出流BufferedWriter
,并将字符串写入该输出流。
然后,System.out.print()
方法中的write(String s)
方法会调用flushBuffer()
方法,将字符输出流的缓冲区的内容刷新到底层输出流中。
关键点1:如果autoFlush
为true
且字符串中包含换行符\n
(即s.indexOf('\n') >= 0
),则调用out.flush()
方法将底层输出流的缓冲区的内容刷新到文件或控制台中。否则不会刷新。
关键点2:在System.out.println()
方法中,首先调用print(String x)
方法打印字符串,然后调用newLine()
方法添加一个换行符。
在newLine()
方法中,实际上是调用print(String x)
方法打印一个换行符,然后调用flushBuffer()
方法将字符输出流的缓冲区的内容刷新到底层输出流中。
关键点3:如果autoFlush
为true
,则调用out.flush()
方法将底层输出流的缓冲区的内容刷新到文件或控制台中。
根据以上解释,可以知道使用System.out.print()
在logcat中看不到日志的原因是,print
方法不会刷新输出流的缓冲区,只有在特定条件下才会刷新。而使用System.out.println()
则会在打印完字符串后添加一个换行符,这个过程会调用flushBuffer()
方法将输出流的缓冲区的内容刷新到底层输出流,因此可以立即看到日志。
所以,解决这个问题的方法就是在使用System.out.print()
打印后,手动调用System.out.flush()
方法来刷新输出流的缓冲区。例如:
System.out.print("test");
System.out.flush();
这样就可以立即在logcat中看到打印的日志了。