IT Share you

Java에서 "new String (…)"이라는 표현의 목적은 무엇입니까?

shareyou 2020. 12. 1. 20:01
반응형

Java에서 "new String (…)"이라는 표현의 목적은 무엇입니까?


온라인 코드 샘플을 보면서 가끔 new 연산자를 사용하여 String 개체에 String 상수를 할당하는 경우가 있습니다.

예를 들면 :

String s;
...
s = new String("Hello World");

물론 이것은

s = "Hello World";

나는이 구문에 익숙하지 않으며 목적이나 효과가 무엇인지 모릅니다. 문자열 상수는 일반적으로 상수 풀에 저장되고 JVM이 문자열 상수를 처리하기 위해 갖는 표현에 관계없이 힙에 할당되는 것이 있습니까?


필요한 곳은 다음과 new String(String)같이 하위 문자열을 새 기본 문자 배열에 복사하도록하는 것입니다.

small=new String(huge.substring(10,20))

그러나이 동작은 불행히도 문서화되지 않았으며 구현에 따라 다릅니다.

큰 파일 (최대 20MiB)을 문자열로 읽고 사실 후에 줄로 조각 할 때 나는 이것에 의해 태워졌습니다. 나는 전체 파일로 구성된 char []를 참조하는 줄에 대한 모든 문자열로 끝났습니다. 안타깝게도 파일을 처리하는 것보다 더 오랜 시간 동안 보유한 몇 줄에 대한 전체 배열에 대한 참조가 의도하지 않게 유지되었습니다 new String().이 문제를 해결하기 위해 사용해야 했습니다.

이를 수행하는 유일한 구현 방식은 다음과 같습니다.

small=new String(huge.substring(10,20).toCharArray());

불행히도 toCharArray()String 생성자에서 배열을 두 번, 한 번, 한 번 복사해야합니다 .

기존의 문자를 복사하여 새 문자열을 얻는 문서화 된 방법이 있어야합니다. 또는 문서를 String(String)더 명확하게하기 위해 개선해야합니다 (함축 된 의미가 있지만 다소 모호하고 해석에 개방적 임).

문서가 설명하지 않는 것을 가정하는 함정

계속되는 의견에 대한 응답으로 Apache Harmony 구현이 무엇인지 관찰하십시오 new String().

public String(String string) {
    value = string.value;
    offset = string.offset;
    count = string.count;
}

맞습니다. 기본 배열의 복사본이 없습니다. 그러나 여전히 다음과 같은 점에서 (Java 7) String 문서를 준수합니다.

인수와 동일한 문자 시퀀스를 나타내도록 새로 만든 String 개체를 초기화합니다. 즉, 새로 생성 된 문자열은 인수 문자열의 복사본입니다. 원본의 명시 적 복사본이 필요하지 않은 경우 문자열은 변경할 수 없으므로이 생성자를 사용할 필요가 없습니다.

두드러진 부분은 "인수 문자열의 복사본 "입니다. "인수 문자열 및 문자열을 지원하는 기본 문자 배열의 복사본"이라고 말하지 않습니다.

하나의 구현이 아닌 설명서에 맞게 프로그래밍해야합니다 .


이것이 유용하다는 것을 알게 된 유일한 시간은 잠금 변수를 선언하는 것입니다.

private final String lock = new String("Database lock");

....

synchronized(lock)
{
    // do something
}

이 경우 Eclipse와 같은 디버깅 도구는 스레드가 현재 보유하고 있거나 대기중인 잠금을 나열 할 때 문자열을 표시합니다. "new String"을 사용해야합니다. 즉, 새 String 객체를 할당해야합니다. 그렇지 않으면 공유 문자열 리터럴이 다른 관련없는 코드에서 잠길 수 있기 때문입니다.


Software Monkey와 Ruggs가 설명한이 생성자의 유일한 유틸리티는 JDK7에서 사라진 것 같습니다. 더 이상 offsetString 클래스에 필드 가 없으며 하위 문자열은 항상

Arrays.copyOfRange(char[] original, int from, int to) 

복사본의 문자 배열을 잘라냅니다.


문자열 s1 = "foo"; 리터럴은 StringPool에 들어가고 s1은 참조합니다.

문자열 s2 = "foo"; 이번에는 "foo"리터럴이 StringPool에서 이미 사용 가능한지 여부를 확인하므로 s2가 동일한 리터럴을 참조합니다.

문자열 s3 = new String ( "foo"); "foo"리터럴은 먼저 StringPool에 생성 된 다음 string arg 생성자를 통해 String Object가 생성됩니다. 즉, new 연산자를 통한 객체 생성으로 인해 힙에 "foo"가 생성되고 s3가이를 참조합니다.

문자열 s4 = new String ( "foo"); s3와 동일

그래서 System.out.println (s1 == s2); // 리터럴 비교로 인해 .

System.out.println (s3 == s4); // 객체 비교로 인해 false (s3 및 s4는 힙의 다른 위치에 생성됨)


글쎄, 그것은 예에서 "..."가 무엇인지에 달려 있습니다. 예를 들어 StringBuffer, 바이트 배열 등이라면 전달하는 데이터로 구성된 String을 얻을 수 있습니다.

But if it's just another String, as in new String("Hello World!"), then it should be replaced by simply "Hello World!", in all cases. Strings are immutable, so cloning one serves no purpose -- it's just more verbose and less efficient to create a new String object just to serve as a duplicate of an existing String (whether it be a literal or another String variable you already have).

In fact, Effective Java (which I highly recommend) uses exactly this as one of its examples of "Avoid creating unnecessary objects":


As an extreme example of what not to do, consider this statement:

String s = new String("stringette");  **//DON'T DO THIS!**

(Effective Java, Second Edition)


Generally, this indicates someone who isn't comfortable with the new-fashioned C++ style of declaring when initialized.

Back in the C days, it wasn't considered good form to define auto variables in an inner scope; C++ eliminated the parser restriction, and Java extended that.

So you see code that has

int q;
for(q=0;q<MAX;q++){
    String s;
    int ix;
    // other stuff
    s = new String("Hello, there!");
    // do something with s
}

In the extreme case, all the declarations may be at the top of a function, and not in enclosed scopes like the for loop here.

IN general, though, the effect of this is to cause a String ctor to be called once, and the resulting String thrown away. (The desire to avoid this is just what led Stroustrup to allow declarations anywhere in the code.) So you are correct that it's unnecessary and bad style at best, and possibly actually bad.


I guess it will depend on the code samples you're seeing.

Most of the times using the class constructor "new String()" in code sample are only to show a very well know java class instead of creating a new one.

You should avoid using it most of the times. Not only because string literals are interned but mainly because string are inmutable. It doesn't make sense have two copies that represent the same object.

While the article mensioned by Ruggs is "interesting" it should not be used unless very specific circumstances, because it could create more damage than good. You'll be coding to an implementation rather than an specification and the same code could not run the same for instance in JRockit, IBM VM, or other.


There are two ways in which Strings can be created in Java. Following are the examples for both the ways: 1) Declare a variable of type String(a class in Java) and assign it to a value which should be put between double quotes. This will create a string in the string pool area of memory. eg: String str = "JAVA";

2)Use the constructor of String class and pass a string(within double quotes) as an argument. eg: String s = new String("JAVA"); This will create a new string JAVA in the main memory and also in the string pool if this string is not already present in string pool.

참고URL : https://stackoverflow.com/questions/390703/what-is-the-purpose-of-the-expression-new-string-in-java

반응형