Java中转换为String类型几种方式注意事项

在Java语言中把其他类型字段转换为String类型的方式有以下四种情况,每种情况形式不同,效果一样,小坑也很多,我们对这几种方法进行总结。

  • (String)Object
  • Object.toString()
  • String.valueOf(Object)
  • Object + “”

方式一:(String)

这是标准的类型转换,将object转成String类型的值。使用这种方法时,需特别小心的是因定义为 Object 类型的对象在转成String时语法检查并不会报错,这将可能导致潜在的错误存在。这时要格外小心。

public static void main(String[] args) {
    Object obj = new Integer(1);
    String s = (String)obj;
}
//抛出异常
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

因为将Integer类型强制转换为String类型,无法通过,因此在使用前最好用instanceof做个类型检查。
但是, 如果obj为null,不会报错,因null值可以强制转换为任何java类类型,(String)null也是合法的。

public static void main(String[] args) {
    Integer obj = new Integer(1);
    String str = (String)obj;//这里会报错:Inconvertible types; cannot cast 'java.lang.Integer' to 'java.lang.String'
}

注意:在Java里不能以【(String)Integer】方式将Integer强制转换成String

因为 String 和 Integer 不是在同一个对象阶层。

Object
     /      
    /        
String     Integer

当你尝试强制转换时,仅仅会在同一个对象阶层转换。比如:

Object
     /
    /
   A
  /
 /
B

在这种情况,(A)objB 或者 (Object)objB 或者 (Object)objA 可以进行转换。

将Integer转换成String可以使用以下方法:

  • String.valueOf(int) 或者
  • Integer.toString(Integer)

很可能是被所有对象可以以字符串的形式表示而导致的,以为所有的对象在使用 (String)obj时,会使用 obj.toString(),所以才造成这种认为理所当然的错觉。

方式二:Object.toString()

Java语言中,从严格意义上任意的java对象都可以调用toString(),这里有一点需要注意,这个值不能为null,否则会报空指针异常。采用这种方法时,通常派生类会覆盖Object里的toString()方法

public static void main(String[] args) {
    Map<String,Object> map = new HashMap<>();
    map.put("name",null);
    map.put("age",18);

    System.out.println(map.get("age").toString());
    //这里取出的值为 null 然后在调用 toString() 就会抛出异常
    System.out.println(map.get("name").toString());
}
//运行结果:
18
Exception in thread "main" java.lang.NullPointerException
	at com.log.test.Test.main(Test.java:13)

方式三:String.valueOf(Object)

String.valueOf(Object)这种方式其实是建立在Object.toString()基础之上的,但不同的是String.valueOf()自带了判断为null的条件,当为null时,String.valueOf()返回的是"null",不是null 如下源码:

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

方式四:Object + “”

这种方式其实很好理解,任何对象和字符串相加都会转换为字符串,这种方式不会出现前面容易发生的空指针异常,但是效率很低,不推荐使用

四种方式效率对比

public class Test {
	public static void main(String[] args) {

        Map m = new HashMap();
        m.put("test", "521521");

        //方式一:(String)Object
        long start1 = System.currentTimeMillis();
        for (Integer i = 0; i < 1000000; i++) {
            String test =(String)m.get("test");
        }
        System.out.print("String test = (String)i:");
        System.out.println(System.currentTimeMillis() - start1);

        //方式二:
        long start2 = System.currentTimeMillis();
        for (Integer i = 0; i < 1000000; i++) {
            String test = m.get("test").toString();
        }
        System.out.print("String test = i.toString():");
        System.out.println( System.currentTimeMillis() - start2);

        //方式三:
        long start3 = System.currentTimeMillis();
        for (Integer i = 0; i < 1000000; i++) {
            String test = String.valueOf(m.get("test"));
        }
        System.out.print("String test = String.valueOf(i):");
        System.out.println( System.currentTimeMillis() - start3);

        //方式四:
        long start4 = System.currentTimeMillis();
        for (Integer i = 0; i < 1000000; i++) {
            String test = m.get("test")+"";
        }
        System.out.print("String test = i + \"\":");
        System.out.println(System.currentTimeMillis() - start4);
    }
}
//第一次运行结果:
String test = (String)i:29
String test = i.toString():26
String test = String.valueOf(i):18
String test = i + "":89
//第二次运行结果:
String test = (String)i:26
String test = i.toString():21
String test = String.valueOf(i):13
String test = i + "":92
//第三次运行结果:
String test = (String)i:28
String test = i.toString():19
String test = String.valueOf(i):13
String test = i + "":103

总结

其实从三次结果中就可以看出,前三种方式效率上大差不差,而第四种方式的效率其实相比而言还是有一定差距的,所以这里使用的时候首先排除第四种方式;我们回头再看第一种方式,这种方式其实有很多坑,也是最容易出问题的,比如 (String)Integer 就会报错;第二种方式容易发生空指针异常问题,xxx.toString()调用的时候一旦 xxx 为null,这时候就会报错;从上面可以看出对于区别比较大的还是对null的处理,总得来说推荐使用String.valueOf(),毕竟不会带来异常。