繁体   English   中英

x.toString() 和 x+"" 的区别

[英]Difference between x.toString() and x+""

回到大学,我的一位教授。 教我们只做x + ""作为从基本类型到字符串的快速转换。
我不记得它在哪个班级我让他参加了一些 Java 和 C++ 课程(我已经有一段时间没有使用过),但我现在在 C#/.Net 中使用它,这是我主要开发的在最近。

对于 int、decimal、float 等基本类型,使用.toString()+""有优势吗? 什么情况下.toString()会更好?

注意:我也看到了.toString() ,那个教授刚刚推荐了+""因为它更短,从那时起我就这样做了,没有质疑它。

好吧,作为旁注,这取决于 x 是什么。 如果 x 是 Java 中的原语,则必须使用其包装器之一调用.toString() ,例如

Integer.toString(x)

我会说使用 toString() 通常更好,因为 x + "",至少在 Java 中,是说您想将两个字符串附加在一起。

就像在这个例子中:

 public static void main(String[] args)
 {
   int x = 3;
   String s = x + "";   
 }

最终,在字节码中,如下所示:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_3
   1:   istore_1
   2:   new #2; //class java/lang/StringBuilder
   5:   dup
   6:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
   9:   iload_1
   10:  invokevirtual   #4; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
   13:  ldc #5; //String 
   15:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   18:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   21:  astore_2
   22:  return

所以它必须创建一个 StringBuilder 来将 "" 和 x 的 String 值附加在一起。 虽然损失的效率并不高,但是仅仅使用 toString 函数并没有太多。

与使用 toString 进行比较:

 public static void main(String[] args)
 {
   int x = 3;
   String s = Integer.toString(x); 
 }

最终结果为:

public static void main(java.lang.String[]);
Code:
 0: iconst_3
 1: istore_1
 2: iload_1
 3: invokestatic    #2; //Method java/lang/Integer.toString:(I)Ljava/lang/String;
 6: astore_2
 7: return

虽然这可能只是我的意见,但使用 .toString 反映了你真正想要的——你想要 x 的字符串值,而使用 x + "" 是一种黑客并说——我想要 x 的字符串值连接和 ””。

旁注:我不能谈论 C# 会发出的中间字节码,但我想像这样的东西。 另外,使用 C#,您可以像引用类型一样轻松地对值类型调用 .ToString(),所以我认为我的建议也适用。

老实说,我认为这种奇怪的建议。

我不能谈论每个特定情况,但一般来说x + ""在 C# 中会做什么(这应该取决于xstring类型的重载+运算符的存在)调用类似string.Concat(x, "")东西string.Concat(x, "")无论如何都会调用x.ToString

在典型情况下,这仅意味着x + ""x.ToString多一个方法调用的开销。 x是某个值类型的变量,但是,这也导致的值x要被装箱,除非用于过载+为的类型具体地存在x (这可能被认为是无用的点,使作为x将如果ToString的类型没有覆盖该方法,则在对ToString的调用中被装箱;这让我感到有点罕见,但它肯定会发生)。

当然,这些都是相当微不足道的差异。 这两种方法的真正区别在于可读性。 根据我的经验, x + ""在 .NET 中不是很惯用,所以我倾向于避免它。 也就是说,这可能只是在我所居住的 .NET 世界中并不常见,而可能有很多 .NET 开发人员在那里这样做。

指出的是,虽然在 Java 中,也许您必须为原始类型的变量x编写笨拙的Integer.toString(x) ,例如int ,在 C# 和 .NET 中一般所有类型(包括所谓的“原始”类型) ) 从object继承,因此可以使用ToString方法(以及GetTypeGetHashCode )。

在 Java 中,对于原始类型( intdouble等),您不能编写.toString()因为这些类型不是对象。 这意味着您可以选择编写类似

x + "";

或使用

Integer.toString(x);

在 C++ 中,您不能使用x + ""进行这种类型的转换,因为这将被视为指针算术并且会给您一个错误的指针。 使用boost::lexical_cast类的东西是进行转换的首选方法。

而且...我对C#一无所知,所以我不会评论它。 :-)

使用x+""没有优点或缺点。 toStringObject类型的方法,每次向字符串添加任何对象时都会隐式调用。

如果您愿意,您始终可以在您的课程中覆盖此方法。

因为字符串是不可变的,所以x+""调用两个函数:x.toString() 和 StringBuffer.append()(至少在 Java 中)。 我想大多数优秀的 JIT 都会简单地将其转换为单个函数调用 x.toString(),但如果不进行实际测试,我无法确定。

没关系,真的。 这极不可能导致任何性能问题。 所以这仍然是个人风格的问题。 使用您或您的团队感到满意的任何东西。

在爪哇,

除了使用原始类型, x+""也适用于null 其中x.toString()抛出NullPointerExceptionx+""返回"null" 这是否更好取决于你,但这是一个区别。

在 C# 中,我会完全无视这个建议,转而使用更具声明性的东西,例如直接使用.ToString

此语法为您提供的唯一潜在优势是,如果xnull ,它将创建一个空字符串。 如果这被认为是您代码中的优势,我会赞成使用扩展方法。

public static string NullSafeToString<T>(this T value) where T : class {
  return value == null ? "" : value.ToString();
}

避免这种情况的另一个原因是因为它会造成优先级混淆。 例如,在不使用参考资料的情况下,您是否确切知道以下场景中z的值?

int x = 42;
int y = 15;
string z = x + y + "";

现在与以下相同的问题

int x = 42;
int y = 15;
string z = x + y.ToString();

对于没有花时间记忆 C# 运算符优先级的普通开发人员,后者更有可能一目了然。 因此我更喜欢它,因为它被误解的可能性较小。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM