2014-12-09 5 views
3

Я пытаюсь создать общий класс MsgRequest, который может установить/получить любой тип параметра. Цель состоит в том, чтобы создать легкий контейнер для различных типов параметров в сообщении и передать его различным вызовам методов.Java generics NoSuchMethodError

public class MsgRequest { 

//private HashMap<String, String> _params = new HashMap<>(); 
private final HashMap<String, Object> _params = new HashMap<>(); 

/** 
* Returns the value of a specified key, if found, null otherwise. 
* @param key 
* @return 
*/ 

public <T> T getX(String key) { 
    return (T) _params.get(key); 
} 


/** 
* Sets/replaces a given key in Message params. 
* @param <T> 
* @param key 
*/ 
public <T> void setX(String key, T element) { 
    //TODO: Implement 2nd param as a generic type. 
    //_params.put(key, element); 
} 

Когда я пытаюсь проверить этот класс, как показано ниже,

@Test 
public void testGetString() { 
    MsgRequest msg = new MsgRequest(); 
    String key = "one"; 
    String val = "This is one."; 
    msg.setX(key, val); 
    //String s = msg.getX("one"); 
    assertTrue("result should be string type", msg.getX("one") instanceof String); 
} 

Затем он бросает java.lang.NoSuchMethodError.

Testcase: testGetString(com.msgx.MsgRequest.MsgRequestTest): Caused an ERROR com.msgx.MsgRequest.MsgRequest.setX(Ljava/lang/String;Ljava/lang/Object;)V java.lang.NoSuchMethodError: com.msgx.MsgRequest.MsgRequest.setX(Ljava/lang/String;Ljava/lang/Object;)V at com.msgx.MsgRequest.MsgRequestTest.testGetString(MsgRequestTest.java:48)

Невозможно разобраться, как исправить это исключение. Какие-либо предложения?

+0

вы можете получить то, что 'T', если я просто показать вам' msg.getX ("один") '? – HuStmpHrrr

+3

Скомпилирует и работает отлично. Какую версию Java и компилятор вы используете? Вы уверены, что вы перекомпилировали свой тест после внесения изменений в класс MsgRequest? –

ответ

2

Сделать класс MsgRequest родовое как

public class MsgRequest<T> { 
    private final Map<String, T> _params = new HashMap<>(); 

    /** 
    * Returns the value of a specified key, if found, null otherwise. 
    * @param key 
    * @return 
    */ 
    public T getX(String key) { 
     return _params.get(key); 
    } 

    /** 
    * Sets/replaces a given key in Message params. 
    * @param <T> 
    * @param key 
    */ 
    public void setX(String key, T element) { 
     _params.put(key, element); 
    } 
} 

И затем использовать его как

@Test 
public void testGetString() { 
    MsgRequest<String> msg = new MsgRequest<>(); 
    String key = "one"; 
    String val = "This is one."; 
    msg.setX(key, val); 
    assertTrue("result should be string type", 
     msg.getX("one") instanceof String); 
} 
+0

Я думаю, что ваш код работает только для хранения на карте одинаково типизированных объектов. Что делать, если мне нужен объект Msg, который может хранить гетерогенные типы? Я не беспокоюсь о безопасности типов, но хотел создать общий контейнер. –

+1

@MupparthyRavindranath. Тогда вы не можете использовать дженерики. Дженерики предназначены для проверки типа времени компиляции и однородных типов. Во время выполнения они стираются. –

+0

Я пытаюсь сделать что-то подобное, как в этом вопросе. http://stackoverflow.com/questions/450807/how-do-i-make-the-method-return-type-generic Но получение NoSuchMethodError. –