2011-09-07 8 views
9

各レコードに属性のセットがあるレコードの記述子として機能するクラスがあると仮定します。Javaの型を保存するにはどうしたらいいですか?

各属性は、可能なタイプのリストは、このような制限されなければならない固有の名前を持っていると、このような整数、文字列、ショート、ダブル、などの特定のJavaタイプに対応する特定のタイプを持っている必要があります...

私は例えばIntegerとStringだけをサポートします。

private HashMap<String, Class> attributeList = new HashMap<String, Class>(); 

上記の例ではHashMapのキー属性名と値が属性(整数または文字列)のタイプでなければならないような属性のリストです。

ハッシュマップの値の定義を制限する最良の方法は何ですか?

答えて

10

もちろん、マップに要素を追加するためにラッパーメソッドを使用し、そこにIntegerとSringのチェックを行うことができます。しかし、あなたはランタイムエラーが発生します。静的なエラーを取得するために型を制限するほうがはるかに優れていることに私は同意します。そのために

、私は実際にInteger.classとString.classを使用していないだろうが、列挙型:

enum Types { String, Integer }; 

private Map<String, Types> attributeList = new HashMap<String, Types>(); 

UPDATE:

は、考えてみれば、他は(そこにありますあなたがの場合、クラスオブジェクトに固執するがあります:偽の列挙型パターンを使用できます。つまり、列挙型のような定数セット(通常は2^iの整数が使用されます)を使用できます。したがって、クラスオブジェクトを定数として定義することができます。もちろん、他のクラスオブジェクトがマップに入れられないことを保証するものではありません。そのため、Joshua Blochの項目30では、「int定数の代わりにenumを使用する」と記載されています。しかしあなたが偽の列挙型チェッカーを使用して、定数の上に追加の型システムを引っ張ってChecker Frameworkを使用することができます。

@SuppressWarnings("fenum:assignment.type.incompatible") 
public class TypeEnum { 
    public static final @Fenum("Types") Class INT_CONST = Integer.class; 
    public static final @Fenum("Types") Class STR_CONST = String.class; 
} 

次にあなたがClass型の制限を使用してマップを定義することができます

private HashMap<String, @Fenum("Types") Class> attributeList 
    = new HashMap<String, @Fenum("Types") Class>(); 

もちろん、Fenum Checkerをコンパイラに含める必要があります。

+0

ほとんど同じ回答を投稿しようとしていました。アプローチは明確で柔軟性があります。しかし、あなたはnull値で何をするつもりですか? –

+0

ヌル値はどうですか? – DaveFar

+0

私は実際にそのようなものを正確に探していました! Thx - それについて考えるよ!ここではその1つのやっていないのはなぜ –

6

HashMapをサブクラス化して、putメソッドをオーバーライドすると、サポートされていない型が使用されたときに例外がスローされますか?私はそれを見るように(ちょうど私の頭の上から...未テスト。)

class MyAttributes extends HashMap<String, Class> { 
    private Set<Class> allowedTypes; 

    public MyAttributes() { 
     allowedTypes = new HashSet<Class>(); 
     allowedTypes.add(Integer.class); 
    } 
    public Class put(String key, Class value) { 
     if(!allowedTypes.contains(value)) { 
      throw new UnsupportedTypeException(); // <-- Your new exception type. 
     } 
     return super.put(key, value); 
    } 
} 
2

、あなたは3つのオプションがあります。

  1. をあなたはそれを持っているような定義を使用し、あなたが引くとき値が正しいタイプの1つであることを確認します。
  2. HashMapをサブクラス化し、要素を追加するときに、サブクラスで型制限を適用します。
  3. 許可するタイプごとに1つずつ、複数のマップを用意し、適切に入力します。

各オプションには長所と短所があり、どのオプションを使用するかによって決定する必要があります。

0

メソッドのオーバーロードはどうですか?

import java.time.LocalDate; 
import java.time.LocalDateTime; 
import java.time.OffsetDateTime; 

public class CarrierDate<T> { 

    private T localDate; 

    private CarrierDate(T localDate) { 
     this.localDate = localDate; 
    } 

    public T getLocalDate() { 
     return localDate; 
    } 

    public static CarrierDate<LocalDate> instance(LocalDate date) { 
     return new CarrierDate<>(date); 
    } 

    public static CarrierDate<LocalDateTime> instance(LocalDateTime date) { 
     return new CarrierDate<>(date); 
    } 

    public static CarrierDate<OffsetDateTime> instance(OffsetDateTime date) { 
     return new CarrierDate<>(date); 
    } 
} 
関連する問題