Effective Java 독서 노트 - 제2장 객체 만들기 및 파괴
제2장 창설 및 파괴 대상
제1조: 구조기 대신 정적 공장 방법 사용
정적 공장 방법의 장점.
1. 이름이 있어 읽기가 편합니다.2. 매번 호출할 때마다 새 대상을 만들지 않아도 된다(구조기가 필요하다).3. 원래 되돌아오는 유형의 모든 하위 유형의 대상을 되돌릴 수 있다(더 유연하다).4. 매개 변수화 유형의 실례를 만들어서 코드를 더욱 간결하게 한다.예:public static HashMap newInstance() {
return new HashMap<>();
}
Map> m =Singleton.newInstance();
정적 공장 방법의 나쁜 점.
1. 클래스는 공유되거나 보호된 구조기가 없으면 이불로 분류할 수 없다.2. 정적 방법과 다를 바 없다(읽기 불편하다?)
제2조: 여러 개의 구조기를 만났을 때 구축기를 고려해야 한다
클래스에는 여러 개의 매개 변수가 있는데 일반적으로 사용하는 중첩 구조기(telescoping constructor) 모드가 좋지 않은 점이 있다. 예를 들어 설정하고 싶지 않은 매개 변수도 어쩔 수 없이 값을 전달해야 한다.
해결 방법은 자바빈스 모드와 Builder 모드를 언급했다.
javaBeans 모드:public class NutritionFacts {
private int servingSize = -1;
private int servings = -1;
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public NutritionFacts() {
}
public void setServingSize(int servingSize) {
this.servingSize = servingSize;
}
public void setServings(int servings) {
this.servings = servings;
}
public void setCalories(int calories) {
this.calories = calories;
}
public void setFat(int fat) {
this.fat = fat;
}
public void setSodium(int sodium) {
this.sodium = sodium;
}
public void setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
}
}
Builder 모드:public class NutritionFacts {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate;
public static class Builder {
private final int servingSize;
private final int servings;
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder setCalories(int calories) {
this.calories = calories;
return this;
}
public Builder setFat(int fat) {
this.fat = fat;
return this;
}
public Builder setSodium(int sodium) {
this.sodium = sodium;
return this;
}
public Builder setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
return this;
}
}
private NutritionFacts(Builder builder) {
servingSize=builder.servingSize;
servings=builder.servings;
calories=builder.calories;
fat=builder.fat;
sodium=builder.sodium;
carbohydrate=builder.carbohydrate;
}
}
Builder 모드 호출 코드:NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
.setCalories(100)
.setSodium(35)
.setCarbohydrate(27)
.build();
클래스 구조기나 정적 플랜트에 여러 매개변수가 있는 경우 Builder 모드를 권장합니다.
제3조: 개인 구조기나 매거 유형으로singleton 속성 강화
Singleton은 단지 한 번만 실례화된 종류를 가리킨다.
java 1.5 이전에 Singleton을 실현하는 두 가지 방법:public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {}
private static Elvis getInstance(){
return INSTANCE;
}
public void leaveTheBuilding() {}
}
또는:public class Elvis2 {
private static Elvis2 ourInstance = new Elvis2();
public static Elvis2 getInstance() {
return ourInstance;
}
private Elvis2() {
}
public void leaveTheBuilding() {}
}
두 번째 방법은 더욱 유연하다.범형우량(제27조)java1.5를 사용한 후singleton을 실현하는 세 번째 방법:public enum Elvis3 {
INSTANCE;
public void leaveTheBuilding() {}
}
제4조: 사유구조기를 통해 실례화할 수 없는 능력을 강화
일부 도구류는 실례화를 원하지 않고, 클래스를 추상류로 만들어서 이 클래스가 실례화되지 못하도록 강요하는 것은 통하지 않는다.
이 클래스에 개인 구조기를 포함시킬 수 있습니다.public class UtilityClass {
private UtilityClass() {
throw new AssertionError();
}
}
이 방법의 부작용: 한 종류를 이불로 분류할 수 없게 한다.
제5조: 불필요한 대상을 만드는 것을 피한다
필요할 때마다 같은 기능을 가진 새로운 대상을 만드는 것이 아니라 대상을 다시 사용하는 것이 좋다.극단적 예:String s = new String("stringette");
이러한 쓰기 방식이 반복에 사용되는 경우 불필요한 String 인스턴스가 수천 개 생성됩니다.일반 쓰기:String s = "stringette";
수정되지 않을 것으로 알려진 일부 가변 대상도 다시 사용할 수 있다.이전 예제 재사용:class Person{
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/*
*
* */
public boolean isBabyBoomer() {
Calendar gmtCal=Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart=gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd=gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0;
}
}
재사용 후 예(호출 속도가 현저히 빨라짐):class Person{
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/*
* ( 250 )
* */
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal=Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START=gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END=gmtCal.getTime();
}
public boolean isBabyBoomer2() {
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
컨테이너 기본 유형이 아닌 기본 유형을 우선적으로 사용하려면 무의식적으로 자동 컨테이너를 조심해야 한다.
예:public static void main(String[] args) {
Long sum=0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
}
sum의 성명은 롱이 아니라 롱이다. 이것은 프로그램이 많은 여분의 롱 실례를 구성했다는 것을 의미한다.운행 시간이 크게 떨어지다.
제6조: 기한이 지난 대상의 응용을 없애다
메모리 유출이 있는 프로그램:public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0) {
throw new EmptyStackException();
}
//
return elements[--size];
/*
*
* */
//Object result = elements[--size];
//elements[size]=null;
//return result;
}
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
}
코드에서 만료된 애플리케이션을 비워 메모리 누수를 해결하려면:Object result = elements[--size];
elements[size]=null;
return result;
제7조: 기한이 지난 방법의 사용을 피한다
종결 방법(finalizer)은 통상적으로 예측할 수 없으며, 일반적인 상황에서는 불필요하다.종결 방법을 사용하면 성능 손실도 있을 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSON
JSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다.
그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다.
저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.
public static HashMap newInstance() {
return new HashMap<>();
}
Map> m =Singleton.newInstance();
public class NutritionFacts {
private int servingSize = -1;
private int servings = -1;
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public NutritionFacts() {
}
public void setServingSize(int servingSize) {
this.servingSize = servingSize;
}
public void setServings(int servings) {
this.servings = servings;
}
public void setCalories(int calories) {
this.calories = calories;
}
public void setFat(int fat) {
this.fat = fat;
}
public void setSodium(int sodium) {
this.sodium = sodium;
}
public void setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
}
}
public class NutritionFacts {
private int servingSize;
private int servings;
private int calories;
private int fat;
private int sodium;
private int carbohydrate;
public static class Builder {
private final int servingSize;
private final int servings;
private int calories = 0;
private int fat = 0;
private int sodium = 0;
private int carbohydrate = 0;
public Builder(int servingSize, int servings) {
this.servingSize = servingSize;
this.servings = servings;
}
public Builder setCalories(int calories) {
this.calories = calories;
return this;
}
public Builder setFat(int fat) {
this.fat = fat;
return this;
}
public Builder setSodium(int sodium) {
this.sodium = sodium;
return this;
}
public Builder setCarbohydrate(int carbohydrate) {
this.carbohydrate = carbohydrate;
return this;
}
}
private NutritionFacts(Builder builder) {
servingSize=builder.servingSize;
servings=builder.servings;
calories=builder.calories;
fat=builder.fat;
sodium=builder.sodium;
carbohydrate=builder.carbohydrate;
}
}
NutritionFacts cocaCola = new NutritionFacts.Builder(240, 8)
.setCalories(100)
.setSodium(35)
.setCarbohydrate(27)
.build();
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {}
private static Elvis getInstance(){
return INSTANCE;
}
public void leaveTheBuilding() {}
}
public class Elvis2 {
private static Elvis2 ourInstance = new Elvis2();
public static Elvis2 getInstance() {
return ourInstance;
}
private Elvis2() {
}
public void leaveTheBuilding() {}
}
public enum Elvis3 {
INSTANCE;
public void leaveTheBuilding() {}
}
public class UtilityClass {
private UtilityClass() {
throw new AssertionError();
}
}
String s = new String("stringette");
String s = "stringette";
class Person{
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/*
*
* */
public boolean isBabyBoomer() {
Calendar gmtCal=Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart=gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd=gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0;
}
}
class Person{
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/*
* ( 250 )
* */
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal=Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START=gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END=gmtCal.getTime();
}
public boolean isBabyBoomer2() {
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
public static void main(String[] args) {
Long sum=0L;
for (long i = 0; i < Integer.MAX_VALUE; i++) {
sum += i;
}
System.out.println(sum);
}
public class Stack {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INITIAL_CAPACITY = 16;
public Stack() {
elements = new Object[DEFAULT_INITIAL_CAPACITY];
}
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0) {
throw new EmptyStackException();
}
//
return elements[--size];
/*
*
* */
//Object result = elements[--size];
//elements[size]=null;
//return result;
}
private void ensureCapacity() {
if (elements.length == size) {
elements = Arrays.copyOf(elements, 2 * size + 1);
}
}
}
Object result = elements[--size];
elements[size]=null;
return result;
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.