class TestNullString { public static void main(String[] args) {
// --------- block 1 --------------------------------------------------
String str = null;
System.out.println(str); // output: null (1)
System.out.println(str + "Test"); // output: nullTest (2)
System.out.println(str.toString()); // java.lang.NullPointerException (3) // --------- block 2 --------------------------------------------------
String str2 = "";
System.out.println(str2);
System.out.println(str2 + "Test");
System.out.println(str2.toString()); }
}
在上面这个简单程序的block 1当中, str是一个字符串对象,初始化为null。
1。为什么(1)可以打印出null, 而(3)却报NullPointerException? println()打印的时候不是缺省调用对象的toString()方法的吗?那(1)和(3)应该同时报错,或者同时输出null啊?2。(2)的输出怎么会是nullTest? 感觉象字符串连接"null" + "Test" 一样,可str明明是null而不是"null"。按照我的想法,至少应该输出"Test"啊?如果str初始化为空字符串(block 2),则一切正常。但是关于block 1的现象在书上找不到解释,请哪位大侠不吝赐教。谢谢
// --------- block 1 --------------------------------------------------
String str = null;
System.out.println(str); // output: null (1)
System.out.println(str + "Test"); // output: nullTest (2)
System.out.println(str.toString()); // java.lang.NullPointerException (3) // --------- block 2 --------------------------------------------------
String str2 = "";
System.out.println(str2);
System.out.println(str2 + "Test");
System.out.println(str2.toString()); }
}
在上面这个简单程序的block 1当中, str是一个字符串对象,初始化为null。
1。为什么(1)可以打印出null, 而(3)却报NullPointerException? println()打印的时候不是缺省调用对象的toString()方法的吗?那(1)和(3)应该同时报错,或者同时输出null啊?2。(2)的输出怎么会是nullTest? 感觉象字符串连接"null" + "Test" 一样,可str明明是null而不是"null"。按照我的想法,至少应该输出"Test"啊?如果str初始化为空字符串(block 2),则一切正常。但是关于block 1的现象在书上找不到解释,请哪位大侠不吝赐教。谢谢
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
print(x) 方法:
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
str + "Test" 会产生一个新的String并分配地址 System.out.println(str + "Test");其实是打印新的那个StringString一旦初始化 就无法改变 在内存中已经分配好了地址
如果要改变String 就会产生一个新的String 并把改变后的String指向新String的地址。String = ""; 也算是分配了内存了
跟String=null完全2个事情
String里面
public String toString() {
return this;
}
就是说,必须得是一个String对象才行。而null,它啥都不是。
Object obj = null;
System.out.println(obj);
还是输出null啊?
System.out.println(str + "Test");其实是打印新的那个String我不懂的是新字符串"nullTest"是怎样产生的,为什么不是"Test"呢?谢谢
我比较笨,看了jdk源码里面这两个方法,啥都看不出来
public static void main(String [] args){
E obj = null;
System.out.println(obj);
try{
System.out.println(obj.toString());
} catch(Exception e){
e.printStackTrace();
}
}
}
class E{
public String toString(){
return "我是空指针!";
}
}
(1)System.out.println(str)方法:
public void println(String x) {
synchronized (this) {
print(x);
newLine();
}
}
(2)print(x) 方法:
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
} //copy自crazylaa,表示感谢
(3)对于"a+b",是这么处理的,如果a和b就基本数据类型,则调用String.valueOf(a),String.valueOf(b),得到两个字符串直接连接起来;如果a和b是object类型包括String类型,则首先判断a和b是否等于null,如果等于则把把它们都转化成字符串“null”,再连接起来,如果不等于null,则调用String.valueOf(a),String.valueOf(b)得到两个字符串连接起来----其他各种情况同理
String str = null;
表示的是 str 所指对象的内存地址为 null;
String str = "Test";
表示的是 str 所指对象的内存地址是一个字符串对象的地址,并且这个字符串对象的toString方法返回"Test"。// 例1
String str = null;
System.out.println(str);例1打印时,JVM发现str所指对象的内存地址为null,JVM针对此类引用直接返回字符串"null"。
所以你看到的是 null 。// 例2
String str = null;
System.out.println(str.toString());例2打印时,JVM将调用str所指对象的toString()方法,但是str所指对象是null,所以JVM抛出NullPointException。
所以你看到的是抛出 NullPointException 异常。// 例3
String str = null;
String str2 = "Test";
System.out.println(str + str2);当out.println参数中含有+时,JVM内部使用了StringBuilder的append方法。也就是说:
例3可以分解为String str = null;
String str2 = "Test";
StringBuilder sb = new StringBuilder();
sb.append(str);
sb.append(str2);
System.out.println(sb.toString());所以你会看到 nullTest 的结果。// 例4 引申(JVM如何进行 + - * / 等简单运算,自己思考吧。)
int i = 10;
int j = 20;
String str = null;
System.out.println(i + j + str);例4会打印出什么呢?
例4可以分解为int i = 10;
int j = 20;
String str = null;
StringBuilder sb = new StringBuilder();
int c = i + j;
sb.append(c);
sb.append(str);
System.out.println(sb.toString());
你改为Object和之前的String是一样的,关键是后面的null没变,你还记得有个问题是这样的,
String str = new String("abc");
这句话产生了几个对象吗?
换作Object obj = null;
只是产生了一个对象obj,然后指向null.而null依然啥都不是.
明白否?
String str = null;
System.out.println(str); // output: null (1)字符串没赋值的时候打印null
//表示未赋值
System.out.println(str + "Test"); // output: nullTest (2)
System.out.println(str.toString()); //java.lang.NullPointerException (3)
//你设置的str=null是表示你的str没有赋值,而str=""表示str赋空值,所以当你用tostring()方法返回
//字符串本身时,找不到str指向的值,所以返回空指针异常
// --------- block 2 --------------------------------------------------
String str2 = "";
System.out.println(str2);
System.out.println(str2 + "Test");
System.out.println(str2.toString()); //
换作Object obj = null;
这里有产生对象吗?只是在将一个对象变量=null,并没有产生对象吧
String str = null;
System.out.println(str); // output: null (1)字符串没赋值的时候打印null
//表示未赋值
System.out.println(str + "Test"); // output: nullTest (2)
System.out.println(str.toString()); //java.lang.NullPointerException (3)
//你设置的str=null是表示你的str没有赋值,而str=""表示str赋空值,所以当你用tostring()方法返回
//字符串本身时,找不到str指向的值,所以返回空指针异常
// --------- block 2 --------------------------------------------------
String str2 = "";
System.out.println(str2);
System.out.println(str2 + "Test");
System.out.println(str2.toString()); //
上面那个事我的另一个号,用错号了,lz要给分请给我这个号(去下载实在是太费分了,现在评论还不给分了郁闷,一切为了混的更好)
如果obj实例化了,那就会打印出obj指向的地址值。
(2)即如果你已经明白(1)为什么输出了,也就是str的值虚拟机会将它置为null,当然"null"+"Test"==nullTest。
(3)str.toString() 它的意思是将str地址中的值转换成String类型。但是str的地址是不存在的,也就是说要将一个值转换,但根本就找不到它,则会有空指针异常。
所以不能用str.toString()方法,没有分配空间的对象都不能调用该对象的方法,否者会出现npe异常
这样当然就是空指针异常
String str = null; //public void println(String x) 打印 String,然后终止该行。
//此方法的行为就像先调用 print(String)然后调用 println()一样。
/*public void print(String s)
打印字符串。如果参数为 null,则打印字符串 "null"。
否则,按照平台的默认字符编码将字符串的字符转换为字节,
并完全以 write(int) 方法的方式写入这些字节。
*/
Object o = null; //public void println(String x) 打印 String,然后终止该行。
//此方法的行为就像先调用 print(String) 然后调用 println() 一样。
//public void print(Object obj)
//打印对象。按照平台的默认字符串编码将 String.valueOf(Object)
//方法生成的字符串转换为字节,并完全以 write(int) 方法的方式写入这些字节。
/*
public static String valueOf(Object obj)
返回 Object 参数的字符串表示形式。
参数:
obj - 一个 Object。
返回:
如果参数为 null,则字符串等于 "null";否则,返回 obj.toString() 的值。
*/
问题1.println()并不是直接调用 .toString()方法,而是要先判断是否为null。
(3)因为对象不存在,所以你调用对象的任何方法都会抛出空指针异常。问题2.字符串的连接操作在JVM中是通过StringBuilder 的append()方法来实现的,即先建立一个StringBuilder 对象s,然后调用s.append()方法把字符串添加到末尾,可以参看Thinking in java的字符串一章开始的部分。append()遇到null的操作如下: /*
public StringBuilder append(StringBuffer sb)
将指定的 StringBuffer 追加到此序列。
按顺序追加 StringBuffer 参数中的字符,此序列将增加该参数的长度。
如果 sb 为 null,则向该序列中追加 4 个 "null" 字符。 在执行 append 方法前,让此字符序列的长度为 n。如果 k 小于 n,
则新字符序列中索引 k 处的字符等于原有序列中索引 k 处的字符;
否则它等于参数 sb 中索引 k-n 处的字符。 参数:
sb - 要追加的 StringBuffer。
返回:
此对象的一个引用。
*/
刚试了试
System.out.println(2+3); 打出来会是5
我还以为会是23呢,我都是想当然的推测的,搞错了,请大家把我写的忘记把,实在不好意思18楼说的才对