2012-11-14 5 views
3

String 메서드에 대한 맞춤 매핑이 있습니다. 이것은 특정 맵 값 유형에 제한되지 않고 String 키가있는 모든 종류의 Map과 함께 사용하기위한 것입니다. 예를 들어지도 값은 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){...} 

또는 뭔가 다른?

또한, 상기 방법은 포함 된 피 각 다소 이런 루프 :

상기 entry 변수 "적절한"타입 맵에 ?의 양립의 조합을 제외하고 (물질을 수행
for(Entry<String, ?> entry : map.entrySet()) { 
    String key = entry.getKey(); 
    String value = entry.getValue().toString(); 
} 

, Object 항목 유형에서).

답변

5

String map2String(Map<String, ?> map){...}은 (? extends Object이 중복)

당신이 호출 할 수 없습니다 때문에 첫 번째가 작동하지 않습니다

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

항목 변수에 대한 적절한 유형이 같은 Entry<String, ?>입니다 정확 의심.

+0

... 최대 득표와 의견이 일치하지 않는 정답과 같이 보입니다. 수락하기 전에 조금 더 기다려주세요. – hyde

1

가장 좋은 방법은 게시 한 첫 번째 예를 사용하는 것입니다. 대신 Object 클래스 유형을 사용하십시오. 그렇지 않으면 다른 클래스에 개체 캐스트 또는 instanceof를 사용하고 아니에요 다른 사람에 대해 좋은 생각

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

해야합니다

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

음, ? extends Object 파생 된 모든 클래스 이후 가장 좋은 건 (하위하지 않습니다)에서 Object. ? extends Object? 사이에는 구별이 없습니다.

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

당신은 어떤 종류없이 String map2String(Map map){...}을 사용 말할 수 있습니다 : 더

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`. 

:

extends 와일드 카드는 경우 경우에 사용할 수 있습니다. 컴파일러가 알려 줄 것입니다 : 지도는 원시 타입입니다. 제네릭 형식 Map에 대한 참조는 매개 변수화 된이어야합니다. 하지만 너무 게으른 마녀 매개 변수에 대해 생각할 수 있습니다. 여러 번 본 사람 유형 : String map2String(Map<?,?> map){...} 경고를 제거합니다. 그러나 그것의 나쁜 접근.

+0

이것은 String 키가있는 맵을 덤프하기위한 것으로 toString()은 value에 사용되므로 Object보다 더 구체적인 유형이 없습니다. 나는 그 질문을 분명히 할 것이다. – hyde

+0

@hyde 그래서'E' 타입을 사용하십시오 : String map2String (Map map) {...} 확장 E는 의미가 있음을 의미합니다. E의 하위 유형 인 모든 유형의 요소를 가진 콜렉션의 모든 구성원을 추가합니다 (그러나 클래스/인터페이스를 ''과 함께 일반으로 선언해야 함) –

+0

'을 사용합니까? ... '단순히''을 사용하는 것보다 유리합니까? 이 경우에는 아무 것도 볼 수 없습니다. – hyde

0

컬렉션 다루기 상속 및 제네릭을 원칙으로 선택합니다.

예를 들어, 나는 인터페이스 또는 추상 기본 클래스를 선언 할 것이며, 같은 컬렉션 유형 매개 변수로 전달됩니다

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

public interface AnimalInterface { 
    public void makeSound(); 
} 

그런 다음 컬렉션이 Map<String, AnimalInterface> 또는 Map<String, ? extends AnimalBaseClass> 하나에 켜집니다. 이렇게하면 첫 번째지도는 AnimalInterface을 구현하는 클래스를 허용하고 두 번째지도는 Dog extends AnimalBaseClass과 같은 추상 기본 클래스 AnimalBaseClass의 하위 클래스를 허용합니다. 귀하의 질문에 대답, 즉 자바 제네릭의 상속 원칙에 자리 잡고 목록을 정의 wildtypes 관련된에 관해서는

: List<Integer>List<Number>의 하위 유형이 아니라 List<Integer> 또는 List<? extends Integer>List<? extends Number>의 하위 유형입니다. 따라서 List<Integer> liList<Number> ln이있는 경우 ln = li과 같을 수 없습니다. 그러나 lnList<? extends Number> ln으로 지정하면 수식이 유효합니다. 그러나 방정식은 유효하지만 Numbers를 목록에 추가하면 ln.add(new Float())과 같은 컴파일 타임 오류가 발생하므로 참조가 내용의 '읽기 전용'버전과 더 비슷 함을 잊지 마십시오. 당신이 당신의 기본 클래스가 될 Object를 원하는 경우 단지 'extends YourBaseClass을'생략,

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

그리고 :

그래서, 당신의 일반적인 방법으로 켜집니다.

관련 문제