Effective Java-オブジェクトの作成と破壊(1)
オブジェクトの作成と破壊
🎯 実行の目的
📌 References.
Effective Java
🚀 Item1. ジェネレータではなく静的パラメータ法を考慮する
クラスは、作成者とは独立して静的メソッドを提供できます.
ここで、静的パラメータメソッドは、クラスインスタンスを返す簡単な静的メソッドです.
EX)
public static Boolean valueOf(boolean b){
return b ? Boolean.TRUE : Boolean.FALSE;
}
この方法には長所もあれば短所もある.まず、その長所を見てみましょう.
第一に、名前をつけることができます
作成者にのみ渡されるパラメータと作成者自体は、返すオブジェクトのプロパティを正しく記述できない可能性があります.
たとえば、
BigInteger
のコンストラクション関数がある場合、小さな値が返されます.BigInteger(int, int, Random)
よりもBigInteger.probablePrime
の方が意味があります.また、パラメータ
Overloading
を入力するだけで作成されるコンストラクタは、コンストラクタを追加すると、どのコンストラクタが何を意味するかを決定する難しいかもしれない
したがって、クラスのインスタンスを作成するときに、名前付き静的パラメータメソッドを使用してインスタンスを作成できます.
ただし、呼び出しのたびにインスタンスを再作成する必要はありません.
静的パラメータメソッドは、インスタンスを事前に作成するか、新しく作成したインスタンスをキャッシュすることによって、これらのインスタンスを回収することができる.
例えば
String
のような不変クラス!String s=new String("Hello");
String s=String.valueOf("Hello");
new String
は、もう1つのインスタンスを作成することを示す.したがって、同じ「Hello」でも、オブジェクトを追加作成するコストが必要になります.valueOf
は、既存のオブジェクトをキャッシュすることによって提供される静的ファクトリ方法である.元の「ハロー」を提供します反復要求に同じオブジェクトを返す方法も
싱글턴 패턴
の基礎である.モノトーンの例
public class Test1 {
private int a;
private int b;
private static final Test1 test1=new Test1();
// 기본 생성자
public Test1() {
}
public Test1(int a, int b) {
this.a=a;
this.b=b;
}
// singleton
private Test1(){
}
public static Test1 getInstanceWithSingleton(){
return test1;
}
}
また、等値インスタンスが1つしかないことを確認できます.等値とは、互いに同じメモリ上に存在するオブジェクトを指します.第三に、戻りタイプを返すサブタイプオブジェクトを返す能力がある.
この機能は、返すオブジェクトのクラスを自由に選択できる柔軟性を提供します.
この柔軟性により、実装クラスを公開することなくオブジェクトを返すことができます.
たとえば
public interface Test2 {
static Test2 getA(){
return new A();
}
static Test2 getB(){
return new B();
}
}
class A implements Test2{
}
class B implements Test2{
}
これらのコードを使用できます.Java 8の前に、
인터페이스
で静的メソッドを宣言することはできません.したがって、静的メソッドがインタフェースに戻る必要がある場合、仲間レベルが入っているそうです
public interface Test2 {
class C implements Test2{
private static final Test2 c=new C();
private C(){
}
public static Test2 getInstance(){
return c;
}
}
}
第四に、入力パラメータに基づいて、異なるクラスのオブジェクトを毎回返すことができる要素の数に応じて、2つのサブクラスのインスタンスを返すことができます.
EnumSet
を例に挙げます.public static <E extends Enum<E>> EnumSet<E> noneOf(Class<E> elementType) {
Enum<?>[] universe = getUniverse(elementType);
if (universe == null)
throw new ClassCastException(elementType + " not an enum");
if (universe.length <= 64)
return new RegularEnumSet<>(elementType, universe);
else
return new JumboEnumSet<>(elementType, universe);
}
上記の静的方法で返されるパラメータ長は、それぞれ RegularEnumSet
およびJumboEnumSet
である.今、欠点を理解してみましょう.
第一に、共通または保護が必要な作成者を継承し、静的メソッドのみではサブクラスを作成できません.
この点を理解するには、継承されたクラスがインスタンスを作成する方法を理解する必要があります.
デフォルトでは、継承されたクラスはクラスを継承します.継承されたクラスを提供するメンバー変数、メンバーメソッドなどを使用するには、まず親クラスの
インスタンス化が必要
ただし、コンストラクション関数が存在せず、静的パラメータメソッドのみが提供されている場合は、サブクラスの作成時に親クラスを作成できないことを示します.
したがって、子クラスが継承後に作成され、親クラスにコンストラクション関数がない場合はエラーが発生します.
第二に、プログラマーは静的な方法を見つけるのが難しい.
これは、APIの説明が作成者のように明確ではない可能性があるためです.ユーザーは静的メソッドクラスを
これは、インスタンス化の方法を理解する必要があることを意味します.
🚀 Item2. コンストラクション関数に多くのパラメータがある場合は、コンストラクタを考慮します。
クラスを作成するとき、プログラマは
점층적 생성자 패턴
を使用します.必須パラメータのみを受け入れる作成者、必須パラメータを受け入れる作成者...これは、ジェネレータを増やし続ける方法を意味します.
これらのポイント積層ジェネレータアレイのパラメータが多ければ多いほど、コンストレイントが多ければ多いほど、コードの作成や読み取りが難しくなります.
これを補うために、
Builder
モードを使用します.どんなパターンなのか見てみましょう.
1.ビルダーオブジェクトに背を向けるには、必要なパラメータのみを使用してビルダーを呼び出します.
2.設定方法を使用して、必要な選択パラメータを設定します.
3.最後に、パラメータなしのコンストラクションメソッドを呼び出してオブジェクトを作成して返します.
コードを見てみましょう.
public class Test1 {
private int a;
private int b;
private int c;
//Builder
public static class Builder{
//필수 매개변수
private final int a;
//선택 매개변수 - 기본값으로 초기화
private int b=0;
private int c=0;
public Builder(int a){
this.a=a;
}
public Builder b(int b){
this.b=b;
return this;
}
public Builder c(int c){
this.c=c;
return this;
}
public Test1 build(){
return new Test1(this);
}
}
private Test1(Builder builder){
this.a= builder.a;
this.b= builder.b;
this.c= builder.c;
}
public static void Main(String[] args){
Test1 build = new Builder(1).b(2).c(3).build();
}
}
コンストラクタの設定方法はコンストラクタ自体を返すため、連続的に呼び出すことができます.コンストラクタモードは、階層設計のクラスとともに使用することもできます.
抽象クラスでは、抽象コンストラクタを持つことができます.具体的なクラスでは、具体的なコンストラクタを持つことができます.
Pizza,java
public abstract class Pizza {
public enum Topping{HAM, CHEESE}
final Set<Topping> toppings;
abstract static class Builder<T extends Builder<T>>{
EnumSet<Topping> toppings=EnumSet.noneOf(Topping.class);
public T addTopping(Topping topping){
toppings.add(Objects.requireNonNull(topping));
return self();
}
abstract Pizza build();
protected abstract T self();
}
Pizza(Builder<?> builder){
toppings=builder.toppings.clone();
}
}
MyPizza.javapublic class MyPizza extends Pizza{
public enum Size{SMALL,MEDIUM,LARGE}
private final Size size;
public static class Builder extends Pizza.Builder<Builder>{
private final Size size;
public Builder(Size size){
this.size=size;
}
@Override
public MyPizza build() {
return new MyPizza(this);
}
@Override
protected Builder self() {
return this;
}
}
private MyPizza(Builder builder){
super(builder);
this.size=builder.size;
}
}
サブクラスのコンストラクタで定義されたコンストラクションメソッドは、特定のサブクラスを返します.これは、PizzaではなくMyPizzaを返すことを意味します.
これらの機能を使用すると、クライアントは変換することなくコンストラクタを作成できます.
欠点を理解しましょう.
今まで勉強しました.
コンストラクタモードは非常に柔軟です.パラメータを選択的に挿入したり、パラメータに基づいて他のオブジェクトを作成したりできます.
欠点は、コンストラクタを生成するコストにつながる可能性があります.
パフォーマンスに敏感な場合、コンストラクタの作成コストも問題になる可能性があります.
したがって、ポイント積層ジェネレータアレイを完全に置き換えることができる(例えば、4つ以上のパラメータがある...)価値のある時、
使用を推奨します.
🚀 Item3. privateジェネレータまたは列挙タイプで単一ループであることを保証
単一インスタンスとは、1つのインスタンスしか作成できないクラスです.
public class Test1 {
private int a;
private int b;
private static final Test1 test1=new Test1();
// 기본 생성자
public Test1() {
}
public Test1(int a, int b) {
this.a=a;
this.b=b;
}
// singleton
private Test1(){
}
public static Test1 getInstanceWithSingleton(){
return test1;
}
}
しかし、モノトーンの欠点も多い.オブジェクトを動的に注入するのは難しい.
serializable
の実施を宣言するだけでは十分ではありません.単一ホイールにインスタンスが1つしかないことを確認する必要があります.これは、逆シリアル化時に新しいインスタンスを作成しないようにする必要があります.
したがって、すべてのフィールド
transient
を宣言し、readResolveメソッドを提供する必要があります.👍 それ以外に、Spring Binはこれらの問題を完全に解決して、それを単色調の状態を維持させます!
さらに、Enumタイプを使用して単輪を作成することもできます.
public enum Test1 {
INSTANCE;
}
この方法はより簡潔で、シリアル化に追加の努力を必要としません.非常に複雑なシリアル化環境でも、インスタンスの出現を完全に回避できます.Reference
この問題について(Effective Java-オブジェクトの作成と破壊(1)), 我々は、より多くの情報をここで見つけました https://velog.io/@sungjin0757/Effective-Java-객체-생성과-파괴-1テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol