有这样一个类,我给实例化了
MenuNode node = new MenuNode();
node.setTitle("在线考试");// 结点名称
node.setId("exam_a");// 结点ID
node.setSelected("false");// 标志复先框是否被选中
node.setIcon("images/organ.gif");// 结点图标
node.setOpenIcon("images/organ.gif");// 结点展开图标
node.setType("organ");// 结点类型
node.setParentId(null);// 父结点ID
node.setChilded("false");// 结点是否为叶子结点Z
后面跟一句:System.out.print(node.getSelected()) ;显示false
System.out.print(node) ;报空指针!!!
调试发现,node是null,一直都是,可是如果是null的话,怎么能set属性呢?太诡异了吧?下面这是node类的内容:
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: MenuNode.javapackage com.ite.oxhide.struts.menu;import java.io.Serializable;public class MenuNode
implements Comparable, Serializable
{ public MenuNode()
{
checked = "true";
disable = "false";
selected = "false";
childed = "true";
} public String getDisable()
{
return disable;
} public void setDisable(String disable)
{
this.disable = disable;
} public String getChecked()
{
return checked;
} public void setChecked(String checked)
{
this.checked = checked;
} public String toString()
{
return null;
} public String getIcon()
{
return icon;
} public void setIcon(String icon)
{
this.icon = icon;
} public String getOpenIcon()
{
return openIcon;
} public void setOpenIcon(String openIcon)
{
this.openIcon = openIcon;
} public Long getOrderNo()
{
return orderNo;
} public void setOrderNo(Long orderNo)
{
this.orderNo = orderNo;
} public String getParentId()
{
return parentId;
} public void setParentId(String parentId)
{
this.parentId = parentId;
} public int compareTo(Object other)
{
MenuNode node = (MenuNode)other;
if(orderNo == null && node.orderNo == null)
return 0;
if(orderNo == null && node.orderNo != null)
return -1;
if(orderNo != null && node.orderNo == null)
return 1;
else
return orderNo.compareTo(node.orderNo);
} public String getTarget()
{
return target;
} public void setTarget(String target)
{
this.target = target;
} public String getChilded()
{
return childed;
} public void setChilded(String childed)
{
this.childed = childed;
} public String getDesc()
{
return desc;
} public void setDesc(String desc)
{
this.desc = desc;
} public String getUrl()
{
return url;
} public void setUrl(String url)
{
this.url = url;
} public String getSelected()
{
return selected;
} public void setSelected(String selected)
{
this.selected = selected;
} public String getType()
{
return type;
} public void setType(String type)
{
this.type = type;
} public String getId()
{
return id;
} public void setId(String id)
{
this.id = id;
} public String getTitle()
{
return title;
} public void setTitle(String title)
{
this.title = title;
} private String title;
private String id;
private String checked;
private String icon;
private String openIcon;
private Long orderNo;
private String parentId;
private String disable;
private String type;
private String selected;
private String url;
private String desc;
private String childed;
private String target;
}
MenuNode node = new MenuNode();
node.setTitle("在线考试");// 结点名称
node.setId("exam_a");// 结点ID
node.setSelected("false");// 标志复先框是否被选中
node.setIcon("images/organ.gif");// 结点图标
node.setOpenIcon("images/organ.gif");// 结点展开图标
node.setType("organ");// 结点类型
node.setParentId(null);// 父结点ID
node.setChilded("false");// 结点是否为叶子结点Z
后面跟一句:System.out.print(node.getSelected()) ;显示false
System.out.print(node) ;报空指针!!!
调试发现,node是null,一直都是,可是如果是null的话,怎么能set属性呢?太诡异了吧?下面这是node类的内容:
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: MenuNode.javapackage com.ite.oxhide.struts.menu;import java.io.Serializable;public class MenuNode
implements Comparable, Serializable
{ public MenuNode()
{
checked = "true";
disable = "false";
selected = "false";
childed = "true";
} public String getDisable()
{
return disable;
} public void setDisable(String disable)
{
this.disable = disable;
} public String getChecked()
{
return checked;
} public void setChecked(String checked)
{
this.checked = checked;
} public String toString()
{
return null;
} public String getIcon()
{
return icon;
} public void setIcon(String icon)
{
this.icon = icon;
} public String getOpenIcon()
{
return openIcon;
} public void setOpenIcon(String openIcon)
{
this.openIcon = openIcon;
} public Long getOrderNo()
{
return orderNo;
} public void setOrderNo(Long orderNo)
{
this.orderNo = orderNo;
} public String getParentId()
{
return parentId;
} public void setParentId(String parentId)
{
this.parentId = parentId;
} public int compareTo(Object other)
{
MenuNode node = (MenuNode)other;
if(orderNo == null && node.orderNo == null)
return 0;
if(orderNo == null && node.orderNo != null)
return -1;
if(orderNo != null && node.orderNo == null)
return 1;
else
return orderNo.compareTo(node.orderNo);
} public String getTarget()
{
return target;
} public void setTarget(String target)
{
this.target = target;
} public String getChilded()
{
return childed;
} public void setChilded(String childed)
{
this.childed = childed;
} public String getDesc()
{
return desc;
} public void setDesc(String desc)
{
this.desc = desc;
} public String getUrl()
{
return url;
} public void setUrl(String url)
{
this.url = url;
} public String getSelected()
{
return selected;
} public void setSelected(String selected)
{
this.selected = selected;
} public String getType()
{
return type;
} public void setType(String type)
{
this.type = type;
} public String getId()
{
return id;
} public void setId(String id)
{
this.id = id;
} public String getTitle()
{
return title;
} public void setTitle(String title)
{
this.title = title;
} private String title;
private String id;
private String checked;
private String icon;
private String openIcon;
private Long orderNo;
private String parentId;
private String disable;
private String type;
private String selected;
private String url;
private String desc;
private String childed;
private String target;
}
public String toString() {
return null;
}
return null;
}
这不是空指针,node是指向一个MenuNode实例的,只是你打印的时候会调用MenuNode类的toString()方法,建议你查看一下toString()方法的应用
相当于 System.out.print(node.toString()),
这样时他会打印出null而不是空指针异常。
node 不为null,只是System.out.print(node)显示值是null,是一个字符串
System.out.print(node==null)来判断它倒底是不是null;
你可以试一下~~会不会空指针异常~~
如果你是
node=null;
System.out.print(node);它会输出“null”这个字符串
public void print(Object obj) {
write(String.valueOf(obj));
}
可见它是调用的String.valueOf(obj)方法public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}此时obj不为空所以会调用obj.toString();
正常情况下一个引用类型toString会调用如下代码 public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}这也是为什么我们平时直接打印一个引用类型会出现MenuNode@ca0b6(以楼主的为例,去掉重写的toString方法)类似的结果而由于重写了toString方法,这时返回了一个null引用,那么接下来任何使用这个返回值的地方一定会出现
NullException,
其实最后会调用Writer这个类的write(str, 0, str.length());这行代码,
所以str.length()时就出现了空指针了
是这样的:
1.System.out.println(youObject);会去调用PrintStream类的public void println(Object x) {
synchronized (this) {
print(x);
newLine();
}
}//然后进入print方法:
public void print(Object obj) {
write(String.valueOf(obj));
}2.调用String.valueOf方法,这个方法如下: public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}上面的obj不会为null,因为你前面实例化了,所以会调用你重写的toString方法。而toString会返回一个null3.再看write方法:private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush && (s.indexOf('\n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
}//textOut.write(s)内容如下:
public void write(String str) throws IOException {
write(str, 0, str.length());//这里的str为null,所以nullPointer了。
}
不知我说的对不?
是这样的:
1.System.out.println(youObject);会去调用PrintStream类的 public void println(Object x) {
synchronized (this) {
print(x);
newLine();
}
} //然后进入print方法:
public void print(Object obj) {
write(String.valueOf(obj));
} 2.调用String.valueOf方法,这个方法如下: public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
上面的obj不会为null,因为你前面实例化了,所以会调用你重写的toString方法。而toString会返回一个null 3.再看write方法: private void write(String s) {
try {
synchronized (this) {
ensureOpen();
textOut.write(s);
textOut.flushBuffer();
charOut.flushBuffer();
if (autoFlush && (s.indexOf('\n') >= 0))
out.flush();
}
}
catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
}
catch (IOException x) {
trouble = true;
}
} //textOut.write(s)内容如下:
public void write(String str) throws IOException {
write(str, 0, str.length());//这里的str为null,所以nullPointer了。
}
不知我说的对不?
print
public void print(Object obj)打印对象。按照平台的默认字符串编码将 String.valueOf(Object) 方法生成的字符串转换为字节,并完全以 write(int) 方法的方式写入这些字节。 参数:
obj - 要打印的 Object
-----------------------------
valueOf
public static String valueOf(Object obj)返回 Object 参数的字符串表示形式。 参数:
obj - 一个 Object。
返回:
如果参数为 null,则字符串等于 "null";否则,返回 obj.toString() 的值。
------------------------------
toString
public String toString()返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于: getClass().getName() + '@' + Integer.toHexString(hashCode())
返回:
该对象的字符串表示形式。
[/code]
调用 System.out.println()方法不会出现空指针,而调用System.out.print()方法,就会出现空指针。
我看了大家提供的源代码,println其实底层也是在调用print方法。为什么会这样。
期待高手。。
一楼的回答真精彩。
o(∩_∩)o 哈哈没事干把toString()方法重写了干嘛啊?
嘿嘿!
唉!
System.out.println(object)//这里是匪夷所思的地方,单单看源代码,和调用print()方法,没什么区别啊,底层也是调用的这个方法啊,这里为什么就不空指针了呢?
System.out.println(object)//相当于System.out.print(String)+newLine()
print(Object)和print(String)是两个不同的方法。