ValueOf ()对 Object.toString ()

在 Java 中,String.valueOf(Object)Object.toString()有什么区别吗? 这些有特定的代码约定吗?

122873 次浏览

String.valueOf(Object)Object.toString()其实是一回事。

如果您看一下 ValueOf (Object)的实现,您会发现 String.valueOf(Object)基本上只是对相应对象的 toString()的一个空安全调用:

Returns the string representation of the Object argument.


Parameters:
obj an Object.
Returns:
if the argument is null, then a string equal to "null";
otherwise, the value of obj.toString() is returned.
See also:
Object.toString()


public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}

根据 Java 文档String.valueOf()返回:

如果参数是 null,则返回等于 "null"的字符串; 否则返回 obj.toString()的值。

因此,除了一个额外的方法调用之外,实际上不应该有什么不同。

而且,在 Object#toString的情况下,如果实例是 null,那么将抛出 NullPointerException,因此可以说,它的值小于 安全

public static void main(String args[]) {
String str = null;
System.out.println(String.valueOf(str));  // This will print a String equal to "null"
System.out.println(str.toString()); // This will throw a NullPointerException
}

下面显示了 java.lang 的实现。正如 jdk8u25源代码中所描述的 String.valueOf。所以根据我的评论,没有区别。它调用“ Object.toString”。对于基元类型,它将其包装为对象形式并在其上调用“ toString”。

见下文:

/*
* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*/




public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}


public static String valueOf(char data[]) {
return new String(data);
}


public static String valueOf(char data[], int offset, int count) {
return new String(data, offset, count);
}


public static String copyValueOf(char data[], int offset, int count) {
return new String(data, offset, count);
}


public static String copyValueOf(char data[]) {
return new String(data);
}


public static String valueOf(boolean b) {
return b ? "true" : "false";
}


public static String valueOf(char c) {
char data[] = {c};
return new String(data, true);
}


public static String valueOf(int i) {
return Integer.toString(i);
}


public static String valueOf(long l) {
return Long.toString(l);
}


public static String valueOf(float f) {
return Float.toString(f);
}


public static String valueOf(double d) {
return Double.toString(d);
}

当参数为 null时,String.valueOf返回 "null",但 Object.toString抛出 NullPointerException,这是唯一的区别。

在 Java 中,String.valueOf (Object)和 Object.toString ()之间有什么区别吗?

是的。(如果你考虑超载的话,情况更是如此!)

正如 Javadoc所解释的,String.valueOf((Object) null)将被 valueOf方法视为特殊情况,并返回值 "null"。相比之下,null.toString()只会给你一个 NPE。

超载

原来是 String.valueOf(null)(注意区别!)是的给一个 NPE... 尽管有 javadoc。真正的解释是模糊的:

  1. String.valueOf有许多重载,但有两个与此相关: String.valueOf(Object)String.valueOf(char[])

  2. 在表达式 String.valueOf(null)中,这两个重载都是 适用,因为 null与任何引用类型兼容。

  3. 当有两个或多个 适用重载时,JLS 表示选择 非常具体参数类型的重载。

  4. 因为 char[]Object的一个子类型,所以它是 具体点

  5. 因此,将调用 String.valueOf(char[])重载。

  6. 如果参数为空数组,则 String.valueOf(char[])抛出 NPE。与 String.valueOf(Object)不同,它没有将 null作为特殊情况处理。

另一个例子更清楚地说明了 valueOf(char[])过载的差异:

char[] abc = new char[]('a', 'b', 'c');
System.out.println(String.valueOf(abc));  // prints "abc"
System.out.println(abc.toString());       // prints "[C@...."

这些有特定的代码约定吗?

没有。

使用最适合您使用它的上下文的需求。(你 需要的格式为 null工作?)

注意: 这不是代码约定。这只是常识编程。它是 更重要,你的代码是 正确比它是遵循一些文体惯例或“最佳实践”的 dogma2


1-您可以通过使用 javap -c检查具有 String.valueOf(null)调用的方法的代码来确认这一点。观察用于调用的重载。

2-请阅读 “没有最佳实践”,并将此参考文献传递给下一个告诉你在编程或 IT 领域做某事是“最佳实践”的人。


个人观点

一些开发人员养成了对空值进行“防御”的坏习惯。因此,您可以看到大量的 null 测试,并将 null 作为特殊情况处理。这个想法似乎是为了防止 NPE 的发生。

我觉得这不是个好主意。特别是,我认为这是一个坏主意,如果你做什么,当你发现一个 null是试图“使好”... 没有考虑为什么有一个 null那里。

一般来说,最好从一开始就避免使用 null... ... 除非 null在应用程序或 API 设计中有非常具体的含义。因此,与其通过大量的防御性编码来避免 NPE,不如让 NPE 发生,然后追踪并修复触发 NPE 的意外 null的来源。

那么,这个理论在这里是如何应用的呢?

那么,如果你想一想,使用 String.valueOf(obj) 可以是一种“做好”的方式。这是要避免的。如果在上下文中意外地发现 objnull,那么最好使用 obj.toString()

最重要的区别是它们处理 null String 引用的方式。

String str = null;
System.out.println("String.valueOf gives : " + String.valueOf(str));//Prints null
System.out.println("String.toString gives : " + str.toString());//This would throw a NullPointerExeption

我不能确切地说出差别是什么,但在字节级操作时似乎有差别。在下面的加密场景中 Object.toString ()产生了一个无法解密的值,而 String.valueOf ()按预期的方式工作..。

private static char[] base64Encode(byte[] bytes)
{
return Base64.encode(bytes);
}


private static String encrypt(String encrypt_this) throws GeneralSecurityException, UnsupportedEncodingException
{
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(PASSWORD));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(SALT, 20));


//THIS FAILED when attempting to decrypt the password
//return base64Encode(pbeCipher.doFinal(encrypt_this.getBytes("UTF-8"))).toString();


//THIS WORKED
return String.valueOf(base64Encode(pbeCipher.doFinal(encrypt_this.getBytes("UTF-8"))));
}//end of encrypt()

ValueOf (Object)和 Object.toString ()之间的区别是:

1) < strong > 如果 string 为 null,

String.valueOf(Object)将返回 "null",而 Object::toString()将抛出空指针异常。

public static void main(String args[]){
String str = null;
    

System.out.println(String.valueOf(str));  // it will print null
System.out.println(str.toString()); // it will throw NullPointerException
}

2)签名:

String 类的 valueOf ()方法是静态的,而 String 类的 toString ()方法是非静态的。

String 的 valueOf ()方法的签名或语法如下:

public static String valueOf(boolean b)
public static String valueOf(char c)
public static String valueOf(char[] c)
public static String valueOf(int i)
public static String valueOf(long l)
public static String valueOf(float f)
public static String valueOf(double d)
public static String valueOf(Object o)

字符串的 toString()方法的签名或语法如下:

public String toString()

这两种方法之间还有一个主要区别,那就是当我们转换的对象是一个数组时。

当您使用 Object.toString ()转换数组时,您将得到某种垃圾值(@后跟数组的哈希码)。

要获得一个人类可读的 toString () ,必须使用 String.valueOf (char []) ; 请注意,这个方法只适用于 char 类型的 Array。我建议使用 Arrays.toString (Object [])将数组转换为 String。

第二个区别是当对象为 null 时,ValueOf ()返回 String“ null”,而 toString ()将返回 null 指针异常。

其他答案已经提到了大多数,但我只是为了完整性才加上这一点:

  1. 基元没有 .toString(),因为它们不是 Object类的实现,所以只能使用 String.valueOf
  2. String.valueOf将把给定的对象 null转换为字符串 "null",而 .toString()将抛出 NullPointerException
  3. 当使用类似于 String s = "" + (...);的内容时,编译器将默认使用 String.valueOf。这就是为什么 Object t = null; String s = "" + t;将导致字符串 "null",而不是 NPE。编辑: 实际上,它将使用 StringBuilder.append,而不是 String.valueOf。所以别理我说的话。

除此之外,这里还有一个实际的用例,其中 String.valueOf.toString()有不同的结果:

假设我们有一个这样的通用方法:

public static <T> T test(){
String str = "test";
return (T) str;
}

我们用类似这样的 Integer类型来命名它: Main.<Integer>test()

当我们使用 String.valueOf创建一个 String 时,它工作得很好:

String s1 = String.valueOf(Main.<Integer>test());
System.out.println(s1);

这将把 test输出到 STDOUT。

然而,如果使用 .toString(),这种方法是行不通的:

String s2 = (Main.<Integer>test()).toString();
System.out.println(s2);

这将导致以下错误:

java.lang.ClassCastException: 类 java.lang.String不能被强制转换为类 java.lang.Integer

上网试试。

至于为什么,我可以参考 这个分开的问题和它的答案。简而言之:

  • 当使用 .toString()时,它将首先编译并计算对象,其中对 T的强制转换(在本例中是从 StringInteger的强制转换)将导致 ClassCastException
  • 当使用 String.valueOf时,它将在编译期间看到通用 T作为 Object,甚至不关心它是否是 Integer。因此它将把 Object强制转换为 Object(编译器只是忽略它)。然后它将使用 String.valueOf(Object),结果如预期的 String。因此,尽管 String.valueOf(Object)将在内部对参数执行 .toString(),但是我们已经跳过了强制转换,并将其视为 Object,因此我们避免了使用 .toString()时出现的 T1。

只是觉得值得一提的是这个额外的差异之间的 String.valueOf.toString()在这里以及。

ValueOf ()可以与没有 toString ()方法的基元类型一起使用。