`
HelloSure
  • 浏览: 310833 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

String的valueOf方法传入null

 
阅读更多
这个问题很有意思
Object obj = null;  
System.out.println(String.valueOf(obj));  
System.out.println(String.valueOf(null));

第一句可以打印出null,但是第二句报空指针异常。

造成这种区别的原因在于两者选取了不同的重载方法。

Java的重载过程分两个阶段。
第一阶段选取所有可获得并且可应用的方法或构造器。看一下String.valueOf()源码,有以下几个重载方法可供选择:
    String valueOf(Object obj)  //①  
    String valueOf(char data[])  //②
    String valueOf(boolean b)  
    String valueOf(char c)   
    ...  


因为基本类型不能赋于null,所以可供选择的方法只有valueOf(char data[])和 valueOf(Object obj)。

第二阶段在第一阶段选取的方法或构造器中选取最精确的一个,如果一个方法或构造器可以接受传递给另一个方法或构造器的任何参数,那么我们就说第一个方法比第二个方法缺乏精确性。方法valueOf(Object obj)可以接收任何传给valueOf(char data[])的参数,我们说方法valueOf(Object obj)相对方法valueOf(char data[])缺乏精确性,所以在重载时会选择方法valueOf(char data[])。

对于方法①
public static String valueOf(Object obj) {
	return (obj == null) ? "null" : obj.toString();
    }

显然会直接返回“null”

对于方法②
public static String valueOf(char data[]) {
	return new String(data);
    }

再看对应的String构造方法:
public String(char value[]) {
	this.offset = 0;
	this.count = value.length;  //※
	this.value = StringValue.from(value);
    }

运行到※处时,会抛出空指针异常。

如果将调用代码修改如下:
    value = String.valueOf((Object)null);  

重载时将会选择valueOf(Object obj)方法,就能回避这个异常。



另一方面想说一下obj是一个引用,不过赋值为null之后就不引用任何东西了。
但毕竟与null不同,null是一个特殊的变量,它什么都不是既不是0,也不是空对象,就是什么都没有。
分享到:
评论
5 楼 xuxiaoyinliu 2016-01-11  
THANKS 第一次遇到这种错误,原来是这样
4 楼 sinat_25176913 2015-11-05  
赞赞赞,一直还在想为什么得到的是一个"null"字符串,原来因为这样
3 楼 我的沉默你不懂 2015-08-25  
在用这个方法的时候想到了这种情行,又懒得试,随手一搜 嘿!还真有试过的!
赞! 
2 楼 mikey_5 2013-01-30  
不错,挺好的,解释的很深入,顶一个!
1 楼 zranye 2012-07-02  
好贴,居然没有人顶。 很强

相关推荐

    Java中区别.toString() ,(String),valueOf()方法

    如果传入的`Object`是`null`,`String.valueOf()`会返回字符串`"null"`,而不是抛出异常。这个方法在处理可能为`null`的对象时很有用,因为它避免了`NullPointerException`。然而,这也可能导致逻辑错误,因为比较`...

    java对象转换String类型的三种方法

    如果传入的对象为null,`String.valueOf()`会返回字符串"null",而不是抛出异常。这个方法内部实际上也是调用了`obj.toString()`,但在null检查后进行,因此避免了可能的`NullPointerException`。此外,对于基本类型...

    String和Date的转换

    另外,如果你只需要日期部分而忽略时间,可以使用`java.sql.Date`的`valueOf()`方法: ```java date = java.sql.Date.valueOf(str); ``` 这将返回一个只包含日期部分的`java.sql.Date`对象,例如2007-01-18。 接...

    not-null-check.rar_c#非空验证

    在函数或方法的开头,你可以使用guard clause立即返回或抛出异常,如果传入的参数是null: ```csharp public void ProcessInput(string input) { if (input == null) throw new ArgumentNullException(nameof...

    java判断String类型是否能转换为int的方法

    1. String到int的转换:在Java中,将String转换成int类型是一种常见的操作,通常使用`Integer.parseInt(String s)`或者`Integer.valueOf(String s)`方法来实现。但如果直接转换一个不是数字的String,将会抛出`...

    Android为textView设置setText的时候报错的讲解方案

    可以使用`String.valueOf()`方法将整型数据转换成字符串类型,这样`setText`就能正确处理了。以下是一个正确的示例: ```java if (list != null) { for (Student stu : list) { tv_name.setText(stu.getName()); ...

    Android 获取经度 纬度 位置信息.rar

      et.append(String.valueOf(newLocation.getLatitude())); //获得纬度   et.append("\n经度:");   et.append(String.valueOf(newLocation.getLongitude()));//获得精度  }  else{ //如果传入的Location对象...

    浅谈SQLite数据库操作常用方法.docx

    String[] whereArgs = {String.valueOf(2)}; db.delete("stu_table", whereClause, whereArgs); // 方法二 String sql = "DELETE FROM stu_table WHERE _id=6"; db.execSQL(sql); } ``` 5. **修改数据** ...

    SQLiteStudy.zip

    ", new String[]{String.valueOf(id)}); ``` “改”即更新数据,使用update()方法,同样需要表名、ContentValues对象以及更新条件: ```java db.update(TABLE_NAME, values, COLUMN_ID + " = ?", new String[]{...

    Android——使用SQLite数据库访问

    ", new String[]{String.valueOf(id)}); ``` 除了上述基本操作,还可以使用事务处理多条操作,提高数据一致性。通过`beginTransaction()`开始事务,`setTransactionSuccessful()`标记事务成功,最后`endTransaction...

    sqlite简单应用列子

    String[] whereArgs = { String.valueOf(1) }; ContentValues updatedValues = new ContentValues(); updatedValues.put(COLUMN_AGE, 21); int rowsAffected = db.update(TABLE_STUDENT, updatedValues, whereClause...

    Android应用源码之sqlite的一些基本操作,包括数据库创建、数据库版本升级、创建表、数据的增删改查.zip

    ", new String[]{String.valueOf(id)}); ``` - **删除数据**:使用`delete()`方法,传入删除条件。 ```java int rowsDeleted = db.delete("MyTable", "id = ?", new String[]{String.valueOf(id)}); ``` 这些基本...

    android 实现Sqlite的增删改查及系统的登录注册功能

    ", new String[]{String.valueOf(id)}); } ``` ### 删除数据 删除数据则通过`delete()`方法完成: ```java public int deleteUser(long id) { SQLiteDatabase db = this.getWritableDatabase(); return db....

    Android 学习 结合界面对Sqlite数据库做增,删,改,查.操作

    ", new String[]{String.valueOf(id)}); } ``` 最后,删除数据使用`delete()`方法: ```java public int deleteUser(long id) { return database.delete(TABLE_NAME, COLUMN_ID + " = ?", new String[]{String....

    ch4-SQLite案例.rar_objecto8y_sqlite_tropicalsw5_增删改查_安卓

    ", new String[]{String.valueOf(userId)}); ``` 4. **删除数据**:使用`delete()`方法,指定表名、删除条件和条件参数。例如: ```java int rowsDeleted = db.delete("Users", "id = ?", new String[]{String....

    android 数据库增删查改 显示

    ", new String[]{String.valueOf(id)}); ``` 3. 修改数据:使用`update()`方法,传入表名、更新内容和WHERE条件。 ```java ContentValues values = new ContentValues(); values.put(COLUMN_NAME, "Jane"); int ...

    sqlite数据库操作

    ", new String[] { String.valueOf(id) }); } ``` ### 6. 使用示例 在Activity或Fragment中,实例化`DatabaseHelper`,然后调用上述方法进行操作。 ```java DatabaseHelper dbHelper = new DatabaseHelper(context...

    android sqlite数据库资料

    ", new String[]{String.valueOf(id)}); } ``` 5. **删除数据**: ```java public void deleteData(int id) { getWritableDatabase().delete(TABLE_NAME, COLUMN_ID + " = ?", new String[]{String.valueOf(id)...

    Android应用源码之数据库SQLite.zip

    ", new String[]{String.valueOf(id)}); } ``` 最后,删除数据用`delete()`方法,同样需要提供删除条件: ```java int deleteUser(long id) { return db.delete(TABLE_NAME, COLUMN_ID + " = ?", new String[]{...

Global site tag (gtag.js) - Google Analytics