문제
Printf는 1.5 릴리스에서 Java에 추가되었지만 출력을 파일이 아닌 문자열로 보내는 방법(sprintf가 C에서 수행하는 작업)을 찾을 수 없는 것 같습니다.이 작업을 수행하는 방법을 아는 사람이 있습니까?
다른 팁
@에릭슨.
문자열은 변경할 수 없는 유형입니다.수정할 수 없으며 새 문자열 인스턴스만 반환합니다.
그렇기 때문에 "foo".format()은 다음과 같이 호출해야 하기 때문에 거의 의미가 없습니다.
string newString = "foo".format();
원래 Java 작성자(및 .NET 작성자)는 "foo"를 수정하지 않고 대신 형식 메서드를 호출하고 입력 문자열을 전달하므로 이 상황에서는 정적 메서드가 더 적합하다고 결정했습니다.
편집하다:허, 이 사이트는 가끔 너무 재미있을 수도 있어요.문자열이 불변 유형이라는 사실을 언급하여 반대 투표를 받았습니다.
다음은 Format()이 인스턴스 메서드로서 멍청한 이유에 대한 예입니다..NET(그리고 아마도 Java에서도)에서 바꾸기()는 인스턴스 메서드입니다.
다음을 수행할 수 있습니다.
"I Like Wine".Replace("Wine","Beer");
그러나 문자열은 불변이기 때문에 아무 일도 일어나지 않습니다.바꾸기는 새 문자열을 반환하려고 시도하지만 아무 것도 할당되지 않습니다.
이로 인해 다음과 같은 일반적인 신인 실수가 많이 발생합니다.
// Contrived Example
inputText.Replace(" ","%20");
다시 말하지만, 아무 일도 일어나지 않습니다. 대신 다음을 수행해야 합니다.
inputText = inputText.Replace(" ","%20");
이제 문자열이 불변이라는 점을 이해하면 완벽하게 이해됩니다.그렇지 않으면 혼란스러울 뿐입니다.바꾸기의 적절한 위치는 String의 정적 메서드인 Format이 있는 곳입니다.
inputText = String.Replace(inputText," ", "%20");
이제 무슨 일이 일어나고 있는지에 대해서는 의문의 여지가 없습니다.
진짜 질문은 왜 이러한 프레임워크의 작성자가 하나는 인스턴스 메서드여야 하고 다른 하나는 정적 메서드로 결정했느냐는 것입니다.내 생각에는 둘 다 정적 메서드로 더 우아하게 표현되지만 Erickson은 둘 다 인스턴스 메서드에 속한다고 생각하는 것 같습니다.
귀하의 의견에 관계없이 사실은 정적 버전을 사용하면 실수할 가능성이 적고 코드를 이해하기가 더 쉽습니다(No Hidden Gotchas).
물론 인스턴스 메서드로 완벽한 몇 가지 메서드가 있습니다. String.Length()를 사용하세요.
int length = "123".Length();
이 상황에서 우리는 "123"을 수정하려고 하는 것이 아니라 단지 검사하고 길이를 반환하는 것이 분명합니다...이것은 인스턴스 메서드에 대한 완벽한 후보입니다.
불변 객체의 인스턴스 메소드에 대한 나의 간단한 규칙:
- 동일한 유형의 새 인스턴스를 반환해야 하는 경우 정적 메서드를 사용하세요.
- 그렇지 않으면 인스턴스 메소드를 사용하십시오.
두 솔루션 모두 printf를 시뮬레이트하지만 방식은 다릅니다.예를 들어 값을 16진수 문자열로 변환하려면 다음 두 가지 해결 방법이 있습니다.
~와 함께
format()
, 가까운sprintf()
:final static String HexChars = "0123456789abcdef"; public static String getHexQuad(long v) { String ret; if(v > 0xffff) ret = getHexQuad(v >> 16); else ret = ""; ret += String.format("%c%c%c%c", HexChars.charAt((int) ((v >> 12) & 0x0f)), HexChars.charAt((int) ((v >> 8) & 0x0f)), HexChars.charAt((int) ((v >> 4) & 0x0f)), HexChars.charAt((int) ( v & 0x0f))); return ret; }
~와 함께
replace(char oldchar , char newchar)
, 다소 빠르지만 꽤 제한적입니다.... ret += "ABCD". replace('A', HexChars.charAt((int) ((v >> 12) & 0x0f))). replace('B', HexChars.charAt((int) ((v >> 8) & 0x0f))). replace('C', HexChars.charAt((int) ((v >> 4) & 0x0f))). replace('D', HexChars.charAt((int) ( v & 0x0f))); ...
문자를 추가하는 것으로 구성된 세 번째 솔루션이 있습니다.
ret
하나씩(문자는 숫자입니다. 서로 더하다!) 예를 들어:... ret += HexChars.charAt((int) ((v >> 12) & 0x0f))); ret += HexChars.charAt((int) ((v >> 8) & 0x0f))); ...
...하지만 그럴거야 정말 못생긴.