String为null的奇怪问题

vivijane 2009-11-29 01:30:09
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的现象在书上找不到解释,请哪位大侠不吝赐教。

谢谢
...全文
882 42 打赏 收藏 转发到动态 举报
写回复
用AI写文章
42 条回复
切换为时间正序
请发表友善的回复…
发表回复
py330316117 2009-11-30
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 yj317608766 的回复:]
对不起,我17楼写的不太对,
刚试了试
      System.out.println(2+3);  打出来会是5
我还以为会是23呢,我都是想当然的推测的,搞错了,请大家把我写的忘记把,实在不好意思

18楼说的才对
[/Quote]
System.out.println("2"+"3");才是23,不想都知道
imcharming 2009-11-29
  • 打赏
  • 举报
回复
又对String有了新的理解了
nnazz 2009-11-29
  • 打赏
  • 举报
回复
顶2楼
cweijiaweil 2009-11-29
  • 打赏
  • 举报
回复
(1)由于你初始化的str是null,也就是说java虚拟机没有给它分配地址,如果将它输出虚拟机就会把没有分配地址的str的值置为null,想这是你明白的。
(2)即如果你已经明白(1)为什么输出了,也就是str的值虚拟机会将它置为null,当然"null"+"Test"==nullTest。
(3)str.toString() 它的意思是将str地址中的值转换成String类型。但是str的地址是不存在的,也就是说要将一个值转换,但根本就找不到它,则会有空指针异常。
xiezhifu 2009-11-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 vivijane 的回复:]
我明白为什么(1)输出null了,不过这又产生另外一个问题,println(String x)只是针对字符串,如果只是一个object呢?比如
      Object obj = null;
      System.out.println(obj);
还是输出null啊?

引用 1 楼 crazylaa 的回复:
(1)System.out.println(str)方法:
public void println(String x) {
synchronized (this) {
    print(x);
    newLine();
}
    }
   print(x) 方法:
  public void print(String s) {
if (s == null) {
    s = "null";
}
write(s);
    }

[/Quote]
obj没有实例化,执行System.out.println(obj)时是打印出obj.toString()的值的,所以打印出null。
如果obj实例化了,那就会打印出obj指向的地址值。
py330316117 2009-11-29
  • 打赏
  • 举报
回复
// --------- block 1 --------------------------------------------------
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要给分请给我这个号(去下载实在是太费分了,现在评论还不给分了郁闷,一切为了混的更好)
wzd814 2009-11-29
  • 打赏
  • 举报
回复
我是来学习的
whut0802 2009-11-29
  • 打赏
  • 举报
回复
public String toString()返回此对象本身(它已经是一个字符串!)。
whut0802 2009-11-29
  • 打赏
  • 举报
回复
18楼。。。顶
wekui 2009-11-29
  • 打赏
  • 举报
回复
up
wekui 2009-11-29
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 howardhewang 的回复:]
换作Object obj = null;
只是产生了一个对象obj,然后指向null.而null依然啥都不是.
明白否?
[/Quote]

换作Object obj = null;
这里有产生对象吗?只是在将一个对象变量=null,并没有产生对象吧
wei_june 2009-11-29
  • 打赏
  • 举报
回复
100分啊
gao512008 2009-11-29
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yj317608766 的回复:]
  (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)得到两个字符串连接起来----其他各种情况同理


[/Quote]
不错
a330316117 2009-11-29
  • 打赏
  • 举报
回复
// --------- block 1 --------------------------------------------------
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()); //
howardhewang 2009-11-29
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 vivijane 的回复:]
我明白为什么(1)输出null了,不过这又产生另外一个问题,println(String x)只是针对字符串,如果只是一个object呢?比如
      Object obj = null;
      System.out.println(obj);
还是输出null啊?

引用 1 楼 crazylaa 的回复:
(1)System.out.println(str)方法:
public void println(String x) {
synchronized (this) {
    print(x);
    newLine();
}
    }
   print(x) 方法:
  public void print(String s) {
if (s == null) {
    s = "null";
}
write(s);
    }



[/Quote]

你改为Object和之前的String是一样的,关键是后面的null没变,你还记得有个问题是这样的,
String str = new String("abc");
这句话产生了几个对象吗?
换作Object obj = null;
只是产生了一个对象obj,然后指向null.而null依然啥都不是.
明白否?
hjjk123 2009-11-29
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yj317608766 的回复:]
  我来终结这道题:
  (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)得到两个字符串连接起来----其他各种情况同理


[/Quote]

顶。。。。
阿士匹灵 2009-11-29
  • 打赏
  • 举报
回复
路过 学习
darxin 2009-11-29
  • 打赏
  • 举报
回复
引用类型的值有两种含义:引用所指对象的内存地址和引用所指对象的内容。
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());
yj317608766 2009-11-29
  • 打赏
  • 举报
回复
对不起,我17楼写的不太对,
刚试了试
System.out.println(2+3); 打出来会是5
我还以为会是23呢,我都是想当然的推测的,搞错了,请大家把我写的忘记把,实在不好意思

18楼说的才对
yj317608766 2009-11-29
  • 打赏
  • 举报
回复
我来终结这道题:
(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)得到两个字符串连接起来----其他各种情况同理

加载更多回复(22)

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧