Java 개발에서 프로그래머는 동일한 기능을 가진 객체를 생성하지 않도록 최선을 다해야 합니다. 이는 메모리를 소비할 뿐만 아니라 프로그램 실행 속도에도 영향을 미치기 때문입니다. 이 경우 객체 재사용을 고려해보세요.
다음으로, 속았는지 확인하기 위해 객체를 재사용하는 몇 가지 시나리오를 살펴보겠습니다. 그렇다면 발견되기 전에 조용히 변경해야 합니다.
다음 두 가지 작성 방식에는 차이가 없어 보이지만, 기본 JVM을 깊이 이해하면 JVM 런타임 상수 풀의 특성을 활용하여 String 객체를 생성하지 않아도 됩니다. 동일한 기능(특히 루프 내부에서 생성됨)은 상당한 성능 최적화를 가져오고 메모리를 절약할 수 있습니다.
잘못된 쓰기 방식
// 每次都会创建一个新的String对象,且不会加入常量池 String name2 = new String("李子捌");
올바른 쓰기 방식
// 正确写法 String name1 = "李子捌";
또한 이제 막 Java 코드를 작성한 프로그래머라면 String, StringBuilder, StringBuffer 클래스의 올바른 사용도 선택해야 합니다. String은 변경할 수 없는 개체이며 일반적으로 변경할 수 없는 문자열을 정의하는 데 사용됩니다. StringBuilder 및 StringBuffer는 문자열 접합과 같은 가변 문자열 작업 시나리오에 사용되며 스레드로부터 안전하며 동기화된 키워드를 사용하여 스레드 동기화를 수행합니다.
// StringBuffer中的append()方法 public synchronized StringBuffer append(String str) { toStringCache = null; super.append(str); return this; } // StringBuilder中的append()方法 public StringBuilder append(String str) { super.append(str); return this; }
Boolean은 일반적으로 사용되는 유형입니다. 개발 시에는 new Boolean() 대신 Boolean.valueof()를 사용해야 합니다. Boolean 클래스가 두 개의 최종 정적 속성을 정의하는 것을 Boolean 소스 코드에서 볼 수 있습니다. .valueof()는 정의된 두 속성을 직접 반환하는 반면, new Boolean()은 새 객체를 생성합니다.
public static final Boolean TRUE = new Boolean(true); public static final Boolean FALSE = new Boolean(false);
Java는 기본 데이터 유형에 대해 자동 언박싱 및 박싱 기능을 제공한다는 것은 이 두 가지 유형을 코드에서 마음대로 사용할 수 있다는 의미입니까? 사실 이론상으로는 코드 수준에서는 문제가 없지만, 구체적인 성능 측면에서는 아직 최적화의 여지가 남아있습니다! ! !
성능 테스트를 해보자
long start = System.currentTimeMillis(); Integer sum = 0; for (int i = 0; i < 100000; i++) { sum += i; } System.out.println(System.currentTimeMillis() - start);
Integer를 사용하면 3밀리초가 걸린다
long start = System.currentTimeMillis(); // 修改Integer 为 int int sum = 0; for (int i = 0; i < 100000; i++) { sum += i; } System.out.println(System.currentTimeMillis() - start);
int를 사용하면 0밀리초가 걸린다
자동 언박싱과 박싱의 사용에 대해서는 실제로 적절하게 할 수 있다고 생각해보자, 결국 때로는 코드 성능이 조금씩 압박을 받는 경우도 있습니다! ! !
정규식은 문자열이 유효한지 확인하는 데 자주 사용됩니다. 먼저 간단한 코드를 살펴보겠습니다. (문제가 한눈에 보이시나요?) !
public static void main(String[] args) { String email = "1057301174@qq.com"; String regex = "^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$"; long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { email.matches(regex); } System.out.println(System.currentTimeMillis() - start); }
이 코드의 실행 시간은 71밀리초로 꽤 빠른 것 같아요!
하지만 매우 간단한 최적화를 수행합니다. 최적화된 코드는 다음과 같습니다.
public static void main(String[] args) { String email = "1057301174@qq.com"; String regex = "^([a-z0-9A-Z]+[-|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$"; Pattern pattern = Pattern.compile(regex); long start = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { //email.matches(regex); pattern.matcher(email); } System.out.println(System.currentTimeMillis() - start); }
코드를 다시 실행하는 데 총 1밀리초가 걸리며 이는 70배 빠릅니다! ! !
이것은 String.matches() 메서드가 루프에서 생성될 때마다 Pattern.compile(regex)을 실행해야 하기 때문이며, 정규 표현식이 필요하기 때문에 Patter 인스턴스 생성 비용이 높기 때문입니다. 유한 상태 기계로 컴파일됩니다. 이 경우 Java API가 더 편리한 메서드 호출을 제공하고 찾기가 쉽지 않기 때문에 성능 고려 사항을 무시하는 경우가 많습니다.
위 내용은 Java에서 불필요한 객체 생성을 피하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!