Java 문자열 맞춤법 상세 정보

일요일에 프로젝트의 논리적 실현에 바빠 토요일에 책장에서 두꺼운 영문판 Thinking In Java를 꺼내 문자열 대상의 연결을 읽었다.이 책을 참고하여 번역을 하고 자신이 생각하는 것을 더해 이 글을 써서 기록하세요.
변경할 수 없는 String 객체
Java에서 String 객체는 변경할 수 없습니다(Immutable).코드에서 여러 개의 String 객체에 대한 별칭을 만들 수 있습니다.하지만 이 별명들은 모두 인용이 같다.
예를 들어 s1과 s2는 모두'droidyue'입니다.com 객체의 별칭입니다. 별칭은 실제 객체에 대한 참조로 저장됩니다.그래서 s1 = s2

String s1 = "droidyue.com";
String s2 = s1;
System.out.println("s1 and s2 has the same reference =" + (s1 == s2));
Java에만 있는 재부팅 연산자
Java에서 재부팅되는 유일한 연산자는 문자열의 결합과 관련된 것입니다. +, +=.이외에도 Java 디자이너는 다른 연산자를 다시 로드할 수 없습니다.
결합 분석
정말 성능 대가가 있나
위의 두 가지를 이해하면 이러한 사고가 있을 수 있다. 만약에 Sting 대상이 변하지 않는다면 여러 개의 (3개 이상) 문자열 결합은 반드시 불필요한 중간 String 대상이 생길 것이다.

String userName = "Andy";
String age = "24";
String job = "Developer";
String info = userName + age + job;
위의 info를 얻으려면userName과age 연결이 임시 String 대상 t1을 생성합니다. 내용은 Andy24이고 t1과job 연결이 최종적으로 우리가 필요로 하는 info 대상을 생성합니다. 그 중에서 중간 t1이 생성되었고 t1이 생성된 후에 자발적으로 회수하지 않으면 일정한 공간을 차지할 것입니다.만약 많은 문자열 (수백 개를 가정하면 대상에 대한 toString의 호출에 많이 나타난다) 의 결합이라면 대가가 더욱 커지고 성능이 한꺼번에 많이 떨어질 것이다.
컴파일러의 최적화 처리
정말 위의 성능 대가가 있을까요? 문자열 연결이 이렇게 자주 사용되는데 특별한 처리 최적화가 없습니까? 답은 있습니다. 이 최적화는 컴파일러에서 컴파일됩니다.java가bytecode에 도착했을 때.
Java 프로그램을 실행하려면 컴파일할 때와 실행할 때 두 시기를 거쳐야 한다.컴파일할 때, 자바 컴파일러는 자바 파일을 바이트 코드로 변환합니다.런타임 시 JVM(JVM)이 컴파일을 실행할 때 생성된 바이트 코드입니다.이러한 두 시기를 통해 자바는 이른바 컴파일링을 하고 곳곳에서 운행했다.
우리는 컴파일러가 어떤 최적화를 했는지 실험해 보자. 우리는 성능 대가가 발생할 수 있는 코드를 제조한다.

public class Concatenation {
 public static void main(String[] args) {
   String userName = "Andy";
   String age = "24";
   String job = "Developer";
   String info = userName + age + job;
   System.out.println(info);
 }
}
네, Concatenation.java를 컴파일해 보세요.Concatenation을 얻다.class
javac Concatenation.java
그리고 우리는 javap를 사용하여 컴파일된 Concatenation을 역컴파일합니다.class 파일.javap -c Concatenation.만약javap 명령을 찾지 못하면, javap가 있는 디렉터리를 환경 변수에 추가하거나 javap의 전체 경로를 사용하는 것을 고려하십시오.

17:22:04-androidyue~/workspace_adt/strings/src$ javap -c Concatenation
Compiled from "Concatenation.java"
public class Concatenation {
 public Concatenation();
  Code:
    0: aload_0
    1: invokespecial #1         // Method java/lang/Object."<init>":()V
    4: return    

 public static void main(java.lang.String[]);
  Code:
    0: ldc      #2         // String Andy
    2: astore_1
    3: ldc      #3         // String 24
    5: astore_2
    6: ldc      #4         // String Developer
    8: astore_3
    9: new      #5         // class java/lang/StringBuilder
   12: dup
   13: invokespecial #6         // Method java/lang/StringBuilder."<init>":()V
   16: aload_1
   17: invokevirtual #7         // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   20: aload_2
   21: invokevirtual #7         // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   24: aload_3
   25: invokevirtual #7         // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   28: invokevirtual #8         // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   31: astore    4
   33: getstatic   #9         // Field java/lang/System.out:Ljava/io/PrintStream;
   36: aload     4
   38: invokevirtual #10         // Method java/io/PrintStream.println:(Ljava/lang/String;)V
   41: return
}

그 중에서ldc,astore 등은 자바 바이트 코드의 지령으로 어셈블리 지령과 유사하다.다음 설명에서는 Java 관련 컨텐트를 사용하여 설명합니다.우리는 위에 많은 StringBuilder가 있는 것을 볼 수 있지만, 우리는 자바 코드에서 표시적으로 호출하지 않는다. 이것이 바로 자바 컴파일러가 최적화한 것이다. 자바 컴파일러가 문자열 연결을 만났을 때 StringBuilder 대상, 뒤에 있는 연결을 만들 것이다. 실제로는 StringBuilder 대상을 호출하는 append 방법이다.이렇게 하면 우리 위에서 걱정하는 문제가 없을 것이다.
컴파일러만으로 최적화?
컴파일러가 우리를 도와 최적화를 한 이상 컴파일러의 최적화만으로 충분하지 않겠는가, 물론 그렇지 않다.
다음은 최적화되지 않은 성능이 낮은 코드를 보겠습니다.

public void implicitUseStringBuilder(String[] values) {
 String result = "";
 for (int i = 0 ; i < values.length; i ++) {
   result += values[i];
 }
 System.out.println(result);
}
javac 컴파일, javap로 보기

public void implicitUseStringBuilder(java.lang.String[]);
  Code:
    0: ldc      #11         // String 
    2: astore_2
    3: iconst_0
    4: istore_3
    5: iload_3
    6: aload_1
    7: arraylength
    8: if_icmpge   38
   11: new      #5         // class java/lang/StringBuilder
   14: dup
   15: invokespecial #6         // Method java/lang/StringBuilder."<init>":()V
   18: aload_2
   19: invokevirtual #7         // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   22: aload_1
   23: iload_3
   24: aaload
   25: invokevirtual #7         // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   28: invokevirtual #8         // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   31: astore_2
   32: iinc     3, 1
   35: goto     5
   38: getstatic   #9         // Field java/lang/System.out:Ljava/io/PrintStream;
   41: aload_2
   42: invokevirtual #10         // Method java/io/PrintStream.println:(Ljava/lang/String;)V
   45: return
그중 8: if_icmpge38과 35:goto5는 하나의 순환을 구성한다.8: if_icmpge 38은 JVM 작업 스택의 정수 대비가 (i 그러나 이 안에 중요한 것이 하나 있다. 바로 StringBuilder 대상의 생성이 순환 사이에서 발생한다는 것이다. 즉, 몇 번의 순환이 몇 개의 StringBuilder 대상을 만드는지 의미하는 것이다. 이렇게 하면 현저히 좋지 않다.적나라하게 수준 낮은 코드네.
조금만 최적화하면 순간적으로 압박을 증가시킵니다.

public void explicitUseStringBuider(String[] values) {
 StringBuilder result = new StringBuilder();
 for (int i = 0; i < values.length; i ++) {
   result.append(values[i]);
 }
}
컴파일된 정보

public void explicitUseStringBuider(java.lang.String[]);
  Code:
    0: new      #5         // class java/lang/StringBuilder
    3: dup
    4: invokespecial #6         // Method java/lang/StringBuilder."<init>":()V
    7: astore_2
    8: iconst_0
    9: istore_3
   10: iload_3
   11: aload_1
   12: arraylength
   13: if_icmpge   30
   16: aload_2
   17: aload_1
   18: iload_3
   19: aaload
   20: invokevirtual #7         // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   23: pop
   24: iinc     3, 1
   27: goto     10
   30: return
위에서 보듯이 13:if_icmpge 30과 27: goto 10은 loop 순환을 구성하고 0: new #5는 순환 밖에 있기 때문에 StringBuilder를 여러 번 만들지 않습니다.
전반적으로 말하자면, 우리는 순환체에서 스텔스나 현식으로 StringBuilder를 만드는 것을 최대한 피해야 한다.그래서 코드를 어떻게 컴파일하고 내부에서 어떻게 실행하는지 아는 사람들은 코드의 등급이 비교적 높다.
상기 문장에 만약 잘못이 있으면 비판하고 바로잡아 주십시오.
이상은 자바 문자열의 연결에 대한 자료를 정리하고 관련 자료를 계속 보충합니다. 본 사이트에 대한 지지에 감사드립니다!

좋은 웹페이지 즐겨찾기