이 과정의 목표는 Java를보다 효과적으로 사용하도록 돕는 것입니다. 객체 생성, 동시성, 직렬화, 반사 및 기타 고급 기능을 포함하여 논의 된 몇 가지 고급 주제가 있습니다. 이 과정은 자바 능력의 여정을 안내합니다.
1. 소개
Tiobe 프로그래밍 언어 순위에서 1995 년 Sun이 개발 한 Java 언어는 세계에서 가장 널리 사용되는 프로그래밍 언어 중 하나입니다. 일반적인 프로그래밍 언어로서 Java Language는 강력한 툴킷 및 런타임 환경, 간단한 구문, 풍부한 플랫폼 지원 (한 번에 작성, 모든 곳에서 실행) 및 매우 활발한 커뮤니티 지원으로 인해 소프트웨어 개발 엔지니어에게 매우 매력적입니다.
이 일련의 기사에서는 Java와 관련된 고급 컨텐츠가 다루어 지므로 독자는 이미 기본 언어 지식을 가지고 있다고 가정합니다. 이것은 완전한 참조 매뉴얼이 아니라 기술을 다음 단계로 끌어 올리는 철저한 가이드입니다.
이 과정에는 많은 코드 스 니펫이 포함되어 있습니다. 비교하기 위해 다른 당사자들은 Java 7과 Java 8의 예를 동시에 제공 할 것입니다.
2. 예제 구성
객체 지향 언어로서, 객체 생성은 아마도 Java 언어에서 가장 중요한 개념 중 하나 일 것입니다. 생성자는 객체 인스턴스의 초기화에 중요한 역할을하며 Java는 생성자를 정의하는 다양한 방법을 제공합니다.
2.1 암시 적 (생성) 시공 방법
Java는 클래스를 정의 할 때 생성자를 선언 할 수 없으며 이것이 생성자가 없음을 의미하지는 않습니다. 다음 수업의 정의를 살펴 보겠습니다.
패키지 com.javacodegeeks.advanced.construction; public class noconstructor {}이 클래스는 생성자를 정의하지 않지만 Java 컴파일러는 암시 적으로 하나를 생성하여 새 키워드를 사용하여 새 개체 인스턴스를 생성 할 수 있습니다.
최종 나체 형성자 NoconstructorInstance = New Noconstructor ();
2.2 매개 변수가없는 구조 방법
매개 변수가없는 생성자는 Java 컴파일을 대체하고 명시 적 선언을 통해 생성자를 생성하는 가장 쉬운 방법입니다.
package com.javacodegeeks.advanced.construction; public class noargconstructor {public noargconstructor () {// 생성자 본문}}새 키워드를 사용하여 새 개체 인스턴스를 만들 때 위의 생성자가 호출됩니다.
2.3 매개 변수와 같은 구조 방법
매개 변수 구조 방법은 가장 흥미롭고 널리 사용되며, 새로운 인스턴스 생성은 매개 변수를 지정하여 사용자 정의됩니다. 다음 예제는 두 개의 매개 변수가있는 생성자를 정의합니다.
패키지 com.javacodegeeks.advanct.consution; 공개 클래스 생성자와 함께 제공 {public yourtuctorwitharguments (Final String Arg1, Final String Arg2) {// 생성자 본문}}}이 시나리오에서는 새 키워드를 사용하여 인스턴스를 만들 때 시공 방법에 정의 된 두 매개 변수를 동시에 제공해야합니다.
최종 생성자와 구조적 구성원을 사용하여 = 새로운 생성자 위장 ( "arg1", "arg2");
흥미롭게 도이 키워드를 통해 생성자를 서로 호출 할 수 있습니다. 실제로, 코드 복제를 줄이고 객체를 기반으로 단일 초기화 항목을 사용하여 여러 생성자를 체인하는 것이 좋습니다. 예를 들어, 다음 코드는 하나의 매개 변수 만있는 생성자를 정의합니다.
public constructorwitharguments (Final String Arg1) {this (arg1, null);}2.4 코드 블록을 초기화합니다
Java는 방법을 구성하는 것 외에도 코드 블록을 초기화하여 초기화하는 논리를 제공합니다. 이 사용법은 드물지만 그것에 대해 더 많이 아는 것은 유해하지 않습니다.
package com.javacodegeeks.advanced.construction; public class 초기화 블록 {{// 초기화 코드}}}반면, 코드 블록 초기화는 매개 변수가없는 암시 적 구조 방법으로 간주 될 수 있습니다. 특정 클래스에서 다중 초기화 코드 블록을 정의 할 수 있으며 다음 코드와 같이 실행될 때 코드에있는 순서로 호출됩니다.
package com.javacodegeeks.advanced.construction; public class 초기화 블록 {{// 초기화 코드} {// 초기화 코드}}실제로 초기화하는 코드 블록은 생성자를 대체하는 것이 아니라 동시에 나타날 수 있습니다. 그러나 생성자 메소드 호출이 곧 시작되기 전에 초기화 코드가 실행됩니다.
package com.javacodegeeks.advanced.construction; public class 초기화 BlockandConstructor {{// 초기화 코드} public initializationBlockandConstructor () {}}2.5 기본값의 구성을 확인하십시오
Java는 명확한 초기화 보증을 제공하며 프로그래머는 초기화 결과를 직접 사용할 수 있습니다. 비 초기 인스턴스 및 클래스 변수 (통계)는 해당 기본값으로 자동 초기화됩니다.
기본값을 입력하십시오
부울
바이트 0
짧은 0
int0
long0l
char/u0000
float0.0f
더블 0.0D
객체 참조 null
표 1
위의 표에서 기본값을 확인하기 위해 다음 예제를 사용합니다.
com.javacodegeeks.advanced.construction; 공개 클래스 초기화 {private boolean booleanmember; 개인 바이트 바이트 멤버; 개인 단기 후원; 개인 int intmember; 사적인 긴 장거리 멤버; 개인 문자 공무원; 개인 플로트 플로트 멤버; 개인 이중 더블 기억; 개인 대상 참조를 참조하십시오. public initializationwithDefaults () {system.out.println ( "booleanmember =" + booleanmember); System.out.println ( "bytemember =" + bytemember); System.out.println ( "shortmember =" + SURMMEMBER); System.out.println ( "intmember =" + intmember); System.out.println ( "longmember =" + longmember); System.out.println ( "charmember =" + arribute.codepointat (new char [] {Charmember}, 0)); System.out.println ( "floatMember =" + floatMember); System.out.println ( "doubleMember =" + doubleMember); System.out.println ( "참조 ember =" + 참조 ember); }}새 키워드를 사용하여 개체를 인스턴스화 한 후 :
최종 초기화를 제공하는 초기화 초기화를 withDefaults = 새로운 초기화 withDefaults (),
콘솔에서 출력 결과를 다음과 같이 볼 수 있습니다.
booleanmember = falseBytemember = 0ShortMember = 0IntMember = 0LongMember = 0Charmember = 0FLOATMEMBER = 0.0DOUBLEMEMBER = 0.0REFERENCEMEMBER = NULL
2.6 가시성
생성자는 Java의 가시성 규칙을 따르며 액세스 제어 수정자를 통해 다른 클래스에서 생성자를 호출 할 수 있는지 여부를 결정할 수 있습니다.
수정 자 패키지 가시성 서브 클래스 가시성 공개 가시성
공개 가시 눈에 보이는 가시 눈에 보이는 가시 가시
보호 된 가시적, 가시 보이지 않는 보이지 않는 보이지 않는 보호
<수정 자 없음> 보이지 않음, 보이지 않으며 보이지 않습니다
개인 보이지 않는 보이지 않는 보이지 않는 보이지 않는 표 2
2.7 쓰레기 재활용
Java (JVM은 정확합니다)는 자동 쓰레기 수집 메커니즘을 가지고 있습니다. 간단히 말해서, 새 객체가 만들어지면 내재를 자동으로 할당합니다. 그런 다음 객체가 더 이상 참조되지 않으면 자동으로 파괴되고 해당 메모리가 재활용됩니다.
Java Garbage Collection은 세대 재활용 메커니즘을 채택하며 "대부분의 물체는 짧은 수명을 가지고있다"는 가정에 근거합니다 (즉, 물체가 만들어진 직후에 인용되지 않으므로 안전하게 파괴 될 수 있습니다). 대부분의 프로그래머는 습관적으로 Java의 객체 생성이 매우 비효율적이라고 생각하므로 가능한 한 새로운 물체의 생성을 피해야합니다. 사실,이 이해는 잘못되었습니다. Java에서 객체를 만드는 오버 헤드는 매우 낮고 빠릅니다. 실제 세대의 큰 오버 헤드는 불필요한 장기 생존 대상이므로 결국 노년으로 마이그레이션되어 세포가 발생하게됩니다.
2.8 객체 최종화기
우리는 시공 방법 및 개체 초기화와 관련된 주제에 대해 이야기했지만, 부정적인 측면 인 물체 파괴를 언급하지 않았습니다. 주로 Java는 쓰레기 수집 메커니즘을 사용하여 물체의 수명주기를 관리하고 불필요한 물체를 파괴하고 필요한 메모리를 자유롭게하는 것이 쓰레기 수집의 책임이됩니다.
그러나 Java는 여전히 여러 리소스를 정리할 책임이있는 소멸자 파이널 라이저와 유사한 또 다른 기능을 제공합니다. Finalizer는 일반적으로 위험한 것으로 보입니다 (다양한 부작용 및 성능 문제를 가져올 수 있기 때문에). 일반적으로 Finalizer는 필요하지 않으므로 피해야합니다 (많은 수의 기본 객체를 포함하는 드문 시나리오를 제외하고). Java 7에 도입 된 Try-With-Resources Syntax 및 Autocclosable 인터페이스는 최종화기의 대안으로 사용할 수 있으며 다음 간결한 코드를 작성할 수 있습니다.
try (final inputStream in = files.newinputStream (path)) {// code}3. 정적 초기화
위에서 우리는 클래스 인스턴스의 구성 및 초기화에 대해 배웠습니다. 또한 Java는 정적 초기화라고하는 클래스 수준의 초기화 구성을 지원합니다. 정적 초기화는 추가 정적 키워드 수정이 있다는 점을 제외하고 위에서 설명한 초기화 코드 블록과 유사합니다. 정적 초기화는 클래스가로드 될 때만 한 번만 수행됩니다. 예는 다음과 같습니다.
코드 블록 초기화와 유사하게, 여러 정적 초기화 블록을 클래스에서 정의 할 수 있으며, 클래스에서의 위치는 초기화시 실행되는 순서를 결정합니다. 예는 다음과 같습니다.
package com.javacodegeeks.advanced.construction; public class staticinitializationBlocks {static {// static 초기화 코드} static {// 정적 초기화 코드}}}정적 초기화 블록은 (클래스가 처음로드 될 때) 여러 스레드에 의해 트리거 될 수 있으므로 JVM 런타임은 초기화 된 코드가 스레드 안전 방식으로 한 번만 실행되도록합니다.
4. 생성자 모드
이해하기 쉬운 생성자 (Creator) 패턴이 수년 동안 Java 커뮤니티에 소개되었습니다. 아래에서는 싱글 톤 모드, 보조 클래스 모드, 공장 모드 및 종속성 주입 (제어 역전이라고도 함) 등 몇 가지 가장 인기있는 것들을 배웁니다.
4.1 싱글 톤 모드
싱글 톤은 소프트웨어 개발 커뮤니티에서 오랜 역사이지만 논란의 여지가있는 모델입니다. 싱글 톤 패턴의 핵심 개념은 언제든지 주어진 클래스가 하나의 객체 만 생성되도록하는 것입니다. 간단하게 들리지만 올바른 스레드 안전 방식으로 객체를 만드는 방법에 대한 많은 토론이 있습니다. 다음 코드는 싱글 톤 패턴 구현의 간단한 버전을 보여줍니다.
package com.javacodegeeks.advanced.construction.patterns; public class naivesingleton {private static naivesingleton 인스턴스; private naivesingleton () {} public static naivesingleton getInstance () {if (instance == null) {instance = new naivesingleton (); } return 인스턴스; }}위의 코드에는 적어도 하나의 문제가 있습니다. 다중 스레드 동시성 시나리오에서 여러 객체가 생성 될 수 있습니다. 적절한 구현 방법 (지연된 로딩은 아님)은 클래스의 정적 '피널'속성을 사용하는 것입니다. 다음과 같이 :
클래스의 최종 속성 com.javacodegeeks.advanced.construction.patterns; public class eagersingleton {private static final eagersingleton 인스턴스 = 새로운 Eagersingleton (); private eagersingleton () {} public static eagersingleton getinstance () {return instance; }}귀중한 리소스를 낭비하고 싶지 않고 실제로 필요한 경우에만 싱글 톤 객체를 생성하기를 원한다면 명시 적 동기화 방법을 사용해야합니다. 이 방법은 다중 스레드 환경에서 동시성을 줄일 수 있습니다 (Java 동시성에 대한 자세한 내용은 Java Advanced 9-Concurrency 모범 사례에 설명되어 있습니다).
패키지 com.javacodegeeks.advanced.construction.patterns; public class lazysingleton {private static lazysingleton 인스턴스; private lazysingleton () {} public static synchronized lazysingleton getinstance () {if (instance == null) {instance = new Lazysingleton (); } return 인스턴스; }}요즘 싱글 톤 패턴은 더 이상 코드를 테스트하기가 쉽지 않기 때문에 많은 시나리오에서 더 이상 좋은 선택으로 간주되지 않습니다. 또한, 의존성 주입 모드의 생성은 또한 싱글 톤 모드를 불필요하게 만듭니다.
4.2 도구/보조 클래스
Tool Class/Help 클래스 패턴은 Java 개발자들 사이에서 매우 인기가 있습니다. 이의 핵심 개념은 비 규정 된 클래스 (개인 생성자를 선언 함)를 사용하는 것입니다. 옵션 최종 (최종 클래스 선언에 대한 자세한 내용은 Java Advanced 3 Class and Interface Design) 키워드 및 정적 메소드에 도입됩니다. 예는 다음과 같습니다.
package com.javacodegeeks.advanced.construction.patterns; public final class helperclass {private helperclass () {} public static void helpermethod1 () {// method body} public static void helpermethod2 () {// method body}}많은 숙련 된 개발자들은이 패턴이 도구 클래스가 다양한 관련이없는 방법을위한 컨테이너를 만들 것이라고 생각합니다. 일부 방법에는 적절한 배치가 없지만 다른 클래스에서 사용해야하므로 실수로 도구 클래스에 배치됩니다. 이 디자인은 대부분의 시나리오에서도 피해야합니다. 코드를 재사용하는 더 나은 방법이 항상있어 코드를 명확하고 간결하게 유지합니다.
4.3 공장 모델
공장 모델은 개발자에게 매우 강력한 도구 인 것으로 입증되었으며 Java에서는 공장 방법과 추상 공장을 구현하는 방법에는 여러 가지가 있습니다. 가장 쉬운 예는 정적 메소드를 사용하여 다음과 같이 특정 클래스 (공장 메소드)의 인스턴스를 반환하는 것입니다.
package com.javacodegeeks.advanced.construction.patterns; public class book {private book (final string title) {} public static book newbook (Final String Title) {return new Book (Title); }}이 방법을 사용하면 코드의 가독성이 향상 될 수 있지만 Newbook Factory Method에 더 풍부한 시나리오를 제공하기가 어렵다는 것은 종종 논란의 여지가 있습니다. 공장 패턴을 구현하는 또 다른 방법은 인터페이스 또는 추상 클래스 (추상 공장)를 사용하는 것입니다. 다음과 같이 공장 인터페이스를 정의합니다.
Public Interface BookFactory {Book Newbook ();}사진 갤러리에 따라 다양한 NewBook 구현을 할 수 있습니다.
공개 수업 도서관은 BookFactory {@override public book newbook () {return new Paperbook (); }} public class kindlibrary emplements bookfactory {@override public book newbook () {return new Kindlebook (); }}이제 BookFactory의 다양한 구현은 특정 책의 차이점을 차단하지만 일반적인 Newbook 방법을 제공합니다.
4.4 종속성 주입
의존성 주입 (제어 역전이라고도 함)은 클래스 디자이너에 의해 양호한 설계 연습으로 간주됩니다. 일부 클래스 인스턴스가 다른 클래스의 인스턴스에 의존하는 경우, 인스턴스 자체가 생성하지 않고 생성자 방법 (또는 세트 방법, 정책 등)을 통해 의존하는 인스턴스를 제공 (주입)해야합니다. 다음 코드를 살펴 보겠습니다.
package com.javacodegeeks.advanced.construction.patterns; import java.text.dateformat; import java.util.date; public class dependent {private final date format = dateformat.getDateInstance (); 공개 문자열 형식 (최종 날짜) {return format.format (날짜); }}종속 클래스는 dateformat 클래스의 인스턴스가 필요하며 객체를 인스턴스화 할 때 dateformat.getDateInstance ()에 의해 얻어집니다. 더 나은 방법은 메소드의 매개 변수를 구성하여 동일한 작업을 수행해야합니다.
패키지 com.javacodegeeks.advanced.construction.patterns; import java.text.dateformat; import java.util.date; public class 종속 {private final date format 형식; public dependent (최종 날짜 format 형식) {this.format = 형식; } 공개 문자열 형식 (최종 날짜 날짜) {return format.format (날짜); }}위의 예에서, 클래스 인스턴스의 모든 종속성은 외부 적으로 제공되므로 DateFormat을 쉽게 조정하고 테스트 코드를 작성하기 쉽습니다.