3

カスタムのMaptoStringメソッドがあります。これは、特定のマップ値タイプに限定されることなく、文字列キーを持つあらゆる種類のマップで使用することを目的としています。マップ値はjavax.jms.Message.getObjectProperty(String name)、たとえばメソッドから取得された可能性があります。または、単なる文字列である可能性があります。

次のうち、使用するのに最も「適切な」メソッドシグネチャはどれですか。また、その理由はどれですか。

String map2String(Map<String, Object> map){...}

また

String map2String(Map<String, ?> map){...}

また

String map2String(Map<String, ? extends Object> map){...}

または(編集を追加)

<E> String map2String(Map<String, ? extends E> map){...}

または、他の何か?

また、このメソッドには、次のようなfor-eachループが含まれています。

for(Entry<String, ?> entry : map.entrySet()) {
    String key = entry.getKey();
    String value = entry.getValue().toString();
}

どちらが変数の「適切な」タイプであるかは重要です(マップ内の、エントリタイプ内entryの互換性のない組み合わせを除く)。?Object

4

3 に答える 3

5

String map2String(Map<String, ?> map){...}正しい(? extends Object冗長)

あなたが電話をかけることができないので、最初のものは機能しません

Map<String,Integer> myMap = {...}
map2String(myMap); // Map<String,Integer>  is not  Map<String,Object>  

エントリ変数の適切なタイプは、予想Entry<String, ?>どおりです。

于 2012-11-14T11:49:37.623 に答える
1

最良の方法は、投稿した最初の例を使用することです。代わりにObject、クラスタイプを使用してください。それ以外の場合は、Objectを他のクラスにキャストするか、使用する必要があり、それはお勧めできませinstanceof

 String map2String(Map<String, YourClass> map){...}

他のものについて:

String map2String(Map<String, ? extends Object> map){...}

? extends Objectから派生したすべてのクラス(サブタイプ)なので、これは最善の策ではありませんObject。との区別はありませ? extends Object?

extends次の場合に使用できるワイルドカード:

class MyClass extends RootClass
....
class YourClass extends RootClass
....
String map2String(Map<String, ? extends RootClass> map)   // this method can fetch argumets by type of Map  `MyClass` and `YourClass`.

さらに遠く:

String map2String(Map<String, ?> map){...}

String map2String(Map map){...}タイプなしで使用したとしましょう。コンパイラは次のように通知します。 マップはraw型です。ジェネリック型Mapへの参照はパラメーター化する必要があります。しかし、あなたはあまりにも怠惰で、魔女のパラメータについて考えることができません。私が何度も見たように、人々は次のように入力します:String map2String(Map<?,?> map){...}警告を削除する。しかし、その悪いアプローチ。

于 2012-11-14T11:38:38.363 に答える
0

コレクションを扱う場合、原則として継承とジェネリックを選択します。

たとえば、インターフェイスまたは抽象基本クラスを宣言し、次のようにコレクションタイプパラメーターとして渡します。

public abstract class AnimalBaseClass {
    //...
    public abstract void makeSound();
}

public interface AnimalInterface {
    public void makeSound();
}

Map<String, AnimalInterface>次に、コレクションはまたはのいずれかに変わりますMap<String, ? extends AnimalBaseClass>。このように、最初のマップはを実装するすべてのクラスを受け入れ、2番目のマップはのようなAnimalInterface抽象基本クラスのすべてのサブクラスを受け入れます。AnimalBaseClassDog extends AnimalBaseClass

リストを定義する際のワイルドタイプに関する質問については、答えはJavaジェネリックの継承の原則にあります。つまりList<Integer>、はのサブタイプではありませんList<Number>が、List<Integer>またはList<? extends Integer>のサブタイプですList<? extends Number>。だから、もしあなたが持っていてList<Integer> liList<Number> lnあなたが同一視することができないならln = li。ただし、方程式が有効であると宣言lnした場合。List<? extends Number> lnただし、方程式は有効ですが、リストに数値を追加すると、のようにコンパイル時エラーが発生するln.add(new Float())ため、参照は「読み取り専用」バージョンのコンテンツのようになることを忘れないでください。

したがって、ジェネリックメソッドは次のようになります。

public <T extends YourBaseClass> String map2String(Map<String, T> map) {
    //do something with your map and return a String object
}

Objectまた、基本クラスになりたい場合は、 ' extends YourBaseClass'を省略してください。

于 2012-11-14T12:36:45.690 に答える