Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java “当我这样做的时候”&引用+;我有一根绳子-为什么_Java - Fatal编程技术网

Java “当我这样做的时候”&引用+;我有一根绳子-为什么

Java “当我这样做的时候”&引用+;我有一根绳子-为什么,java,Java,请首先理解,我完全理解,当我使用“+int”时,Java将返回一个字符串 我真的不确定的是在记忆方面到底发生了什么。java究竟是如何执行这种转换的。我的意思非常深刻,不是“自动拳击”之类的:) 我希望有更深入了解的人能解释到底做了什么 将+视为字符串串联,因为字符串位于操作数的一侧-这也适用于1+“”。因此,1被隐式转换为字符串“1”,并与之连接,从而产生“+”1”=>“1” 这有时被用作将整型变量转换为字符串的快速而肮脏的方法,例如 String s = "" + myInt; 但做到这一

请首先理解,我完全理解,当我使用“+int”时,Java将返回一个字符串

我真的不确定的是在记忆方面到底发生了什么。java究竟是如何执行这种转换的。我的意思非常深刻,不是“自动拳击”之类的:)


我希望有更深入了解的人能解释到底做了什么

+
视为字符串串联,因为字符串位于操作数的一侧-这也适用于
1+“”
。因此,
1
被隐式转换为字符串
“1”
,并与之连接,从而产生
“+”1”
=>
“1”

这有时被用作将整型变量转换为字符串的快速而肮脏的方法,例如

String s = "" + myInt;
但做到这一点的“正确”方法是:

String s = Integer.toString(myInt);
或者:

String s = String.valueOf(myInt);
编辑:

为了澄清这一点,编译器会做出这个决定,并插入代码,在执行串联之前将整数转换为字符串

因此,编译器基本上可以看到:

String s = "" + myInt;
并有效地创建与

String s = "" + String.valueOf(myInt)

虽然它实际上可能会优化连接。a“+”b”只是StringBuilder.append(“a”).append(“b”)的语法糖,因为您可以.append(1),它会自动将其转换为您看到的字符串。

Java语言规范

任何类型都可以通过字符串转换为类型 字符串转换

x的值 原始类型T首先转换为 一个参考值,好像通过给出它 作为适当类的参数 实例创建表达式:

  • 如果T是布尔值,则使用new 布尔(x)
  • 如果T是char,则使用 新字符(x)
  • 如果T是字节, short或int,然后使用new 整数(x)
  • 如果T很长,则使用 新长(x)
  • 如果T是float,则使用 新浮点数(x)
  • 如果T是双的,那么 使用新的Double(x)
此引用 然后将值转换为字符串类型 通过字符串转换

现在只是 需要对参考值进行修改 已考虑。如果引用为null, 它被转换为字符串“null” (四个ASCII字符n、u、l、l)。 否则,执行转换 好像是通过调用toString 引用对象的方法 没有参数;但是如果 调用toString方法的值为null, 然后使用字符串“null” 相反

toString方法由 原始类对象;许多类 覆盖它,特别是布尔值, 字符,整数,长,浮点, 双人,还有绳子

实际上,对于“+1”,编译器创建了一个值为“1”的字符串常量字符串,并将其放入常量池-因此在运行时不会执行任何操作

如果有“”+x(其中x是一个int变量),则会得到以下字节码(来自当前的JDK 1.6):

0:new#2;//类java/lang/StringBuilder
3:dup
4:invokespecial#3;//方法java/lang/StringBuilder。”“:()V
7:ldc#4;//字符串
9:invokevirtual#5;//方法java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
12:aload_0
13:排列长度
14:invokevirtual#6;//方法java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
17:invokevirtual#7;//方法java/lang/StringBuilder.toString:()Ljava/lang/String;
20:astore_1
21:返回
因此,它创建一个StringBuilder,将“”附加到它,然后将int值附加到它,然后在StringBuilder实例上调用toString

在StringBuilder.append(int)方法中,它最终调用Integer.getChars(包私有方法)


您可以在JDK src.zip(或src.jar)的副本中查找append和getChars的源代码。

这些引用中的一些是为了相关性而编辑的,可能会添加强调

如果只有一个操作数表达式的类型为
String
,则在运行时对另一个操作数执行字符串转换以生成字符串。结果是对两个操作数字符串串联的
String
对象的引用

  • 原语类型T的值
    x
    首先被转换为参考值,就像将其作为适当的类实例创建表达式的参数一样:
    • 如果T是
      byte
      short
      int
      ,则使用
      新整数(x)
  • 现在只需要考虑参考值。转换是通过调用
    toString()
    方法执行的
根据此规范,
”“+i
的计算结果为,就好像它被写为
”“+new Integer(i).toString()
。该操作是字符串串联,结果是一个字符串

一定要注意上面段落中的短语“仿佛”;只有正确的行为被精确地指定,但如何在引擎盖下实现则留给实现

目前我在讨论中忽略了以下几点:

  • null
    始终转换为
    “null”
  • 编译时常量()的内联
  • 使用可变的
    StringBuffer
    /
    StringBuilder
    ()

自动装箱是将一个原语(int)转换为一个对象(Integer),这就是所谓的强制。我认为他给出了一个简单、无用的“自动装箱”答案的例子。每当我看到有人通过将int连接为空字符串将其转换为字符串时,我都会畏缩。Integer.toString(int)Rob-这很好,但我真正的问题是java的INARD如何做到这一点。请注意,java的内部如何做到这一点将取决于实现
  0:   new     #2; //class java/lang/StringBuilder
  3:   dup
  4:   invokespecial   #3; //Method java/lang/StringBuilder."<init>":()V
  7:   ldc     #4; //String
  9:   invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  12:  aload_0
  13:  arraylength
  14:  invokevirtual   #6; //Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  17:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
  20:  astore_1
  21:  return