インタビューの準備中に、誰かが Java でクラス/メソッドを読み取り専用にする方法を知っていると言いました。少し調べてみましたが、具体的なものは見つかりませんでした。
おそらく、この質問は私が思っているよりも簡単に答えることができますが、Java でクラスまたはメソッドを読み取り専用にする方法は何でしょうか?
immutable
1つの解決策は、読み取り専用クラスに属するオブジェクトを作成することです。クラス内のメソッドがオブジェクトの内部状態を変更しないように、クラスを定義できます。このようなクラスでは、内部状態しか読み取れないため、エイリアシングは影響を与えません。したがって、多くのコードが同じオブジェクトを読み取っている場合でも問題はありません。
不変オブジェクトを作成するには、次のリンクを探してください。
次のコードは、クラスが常に読み取り専用であることを保証しますが、抜け穴を見つけた場合は、ここに投稿してください。
import java.io.Serializable;
final public class ImmutableClass implements Cloneable,Serializable {
private static final long serialVersionUID = 6488148163144293060L;
private static volatile ImmutableClass instance;
private ImmutableClass() {
// no-op
System.out.println("instance created : " + this.hashCode());
}
/**
* Lazy Instantiation
*
* @return
*/
public static ImmutableClass getInstance() {
if (instance == null) {
synchronized (ImmutableClass.class) {
System.out.println("aquired lock");
if (instance == null) {
instance = new ImmutableClass() {
};
}
System.out.println("released lock");
}
}
return instance;
}
public Object readResolve() {
System.out.println("readResolve()");
return getInstance();
}
@Override
public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
}
オブジェクトの読み取り専用バージョンが必要だとしましょう。
ケース 1: クラスに他のオブジェクトへのポインタではないフィールドが含まれている場合:
public class Person{
private String name;
//Getters n Setters
}
この場合、このクラスのコピーを返し、Person を受け入れるコンストラクターを記述できます。Person オブジェクトを取得したい人は誰でもこのオブジェクトのコピーを持つため、Setter 操作は元のオブジェクトに影響しません (文字列は不変です)。
ケース 2: オブジェクトに別のオブジェクトまたはリストまたはマップへのポインターが含まれている場合
この場合、クラスに読み取り専用メソッド (Getters) のみを持つインターフェイスを実装させ、オブジェクトを返す場所はどこでも、このインターフェイスを返すように変更して、クライアントが読み取り専用メソッドのみにアクセスできるようにします。
例えば:
class Person implements ReadOnly{
String name;
.. assume pointers also in here
// Getter n Setters
public PersonReadOnly(){
return this;
}
}
interface PersonReadOnly {
public String getName();
}
簡単なルール: パブリック フィールドを持たず、パブリック セッター メソッドもありません。
たとえば、以下のクラスを参照してください。
final class AReadOnlyClass
{
private int anInt;
public int GetAnInt()
{
return anInt;
}
}