2016-12-09 107 views
0

我想在泛型類型使用反射的Java getMethod()泛型類型

我有這個類

package it.ciro.service; 

import it.ciro.dao.SysMyAbDao; 
import org.apache.log4j.Logger; 

import java.io.Serializable; 
import java.lang.reflect.InvocationTargetException; 
import java.lang.reflect.Method; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.Map; 

/** 
* Created by ciro on 09/12/2016. 
*/ 
public class SelectOption<E extends Serializable> { 

    private SysMyAbDao dao; 
    private Class<E> entity; 
    private ArrayList<Class<E>> entityAll; 
    private Map<String,String> optionList = new HashMap<String,String>(); 
    protected Logger logger; 

    public SelectOption(SysMyAbDao dao,Class<E> entity,String idName, String labelName){ 
     logger = Logger.getLogger(this.getClass()); 

     this.dao = dao; 
     this.entity = entity; 
     entityAll = dao.findAll(); 
     try{ 
      Method idMethod = this.entity.getMethod(idName); 
      Method labelMethod = this.entity.getClass().getMethod(labelName); 
      for (Class<E> single : entityAll) { 
       optionList.put((String)idMethod.invoke(single),(String)labelMethod.invoke(single)); 
      } 
     }catch (NoSuchMethodException ex){ 
      ex.printStackTrace(); 
      logger.error(ex.getMessage()); 
     } catch (InvocationTargetException e) { 
      logger.error(e.getMessage()); 
     } catch (IllegalAccessException e) { 
      logger.error(e.getMessage()); 
     } 
    } 

    public Map<String, String> getOptionList() { 
     return optionList; 
    } 
} 

,並在我的控制器

SelectOption<GeoProvince> selectOption = new SelectOption(geoRegionDao,GeoRegion.class,"idGeoRegion","name"); 

,但我得到

java.lang.NoSuchMethodException: java.lang.Class.idGeoRegion() 

java search on generic ty pe e不是我在構造函數中使用的類型

我期望搜索是關於我在控制器中花費的類型。在GeoRegion類中存在該方法。

這是SysMyAbDao

public abstract class SysMyAbDao<T, E, Id extends Serializable> { 
    protected String message; 
    protected Boolean status; 
    protected T t ; 
    protected Logger logger; 
    protected Long totalRow; 
    private Class<T> type; 

    public SysMyAbDao(Class<T> type){ 
     this.type = type; 
    } 
    ..... 

GeoRegion類

public class GeoRegion implements java.io.Serializable { 

    private int idRegion; 
    private String name; 
    private String code; 
    private Set<GeoProvince> geoProvinces = new HashSet<GeoProvince>(0); 
    private Set<GeoCity> geoCities = new HashSet<GeoCity>(0); 

    public GeoRegion() { 
    } 


    public GeoRegion(int idRegion) { 
     this.idRegion = idRegion; 
    } 
    public GeoRegion(int idRegion, String name, String code, Set<GeoProvince> geoProvinces, Set<GeoCity> geoCities) { 
     this.idRegion = idRegion; 
     this.name = name; 
     this.code = code; 
     this.geoProvinces = geoProvinces; 
     this.geoCities = geoCities; 
    } 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="id_region", unique=true, nullable=false) 
    public int getIdRegion() { 
     return this.idRegion; 
    } 

    public void setIdRegion(int idRegion) { 
     this.idRegion = idRegion; 
    } 


    @Column(name="name") 
    public String getName() { 
     return this.name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 


    @Column(name="code", unique=true) 
    public String getCode() { 
     return this.code; 
    } 

    public void setCode(String code) { 
     this.code = code; 
    } 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="geoRegion") 
    public Set<GeoProvince> getGeoProvinces() { 
     return this.geoProvinces; 
    } 

    public void setGeoProvinces(Set<GeoProvince> geoProvinces) { 
     this.geoProvinces = geoProvinces; 
    } 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="geoRegion") 
    public Set<GeoCity> getGeoCities() { 
     return this.geoCities; 
    } 

    public void setGeoCities(Set<GeoCity> geoCities) { 
     this.geoCities = geoCities; 
    } 
} 
+0

你能張貼'GeoRegion'類的代碼? – developer

+0

@javaguy發佈 – ciro

回答

0

您正在試圖調用你的方法上single,這是一個Class對象。

我在代碼中看不到GeoRegion的任何實例。但爲了這個工作,你需要使用這種方法對其中的一個:

E instance = getSomeObjectFromSomewhere(); 
optionList.put((String)idMethod.invoke(instance),(String)labelMethod.invoke(instance)); 
+0

我不知道在此之前,如果第一類GeoRegion或其他類 – ciro

+0

是的,你說得對。相應地更新答案。 –

2

你在這一行額外getClass()

Method labelMethod = this.entity.getClass().getMethod(labelName); 

事實上,你在呼喚getClass()Class<E>對象。由於Class<E>的類別不是E,而是java.lang.Class,因此您將獲得您發佈的NoSuchMethodException

此外,您正在調用您的方法(single在您的情況下)的實例應該是E類型,而不是類型Class<E>

總的來說,你最終會得到這樣的:

public SelectOption(SysMyAbDao<E, ?, ? extends Serializable> dao, 
        Class<E> entityClass, 
        String idName, 
        String labelName) { 
    this.dao = dao; 
    this.entityClass = entityClass; 
    this.entityAll = dao.findAll(); // make sure your SysMyAbDao<E, ?, ?>#findAll() returns a Collection<E> 
    try{ 
     Method idMethod = this.entityClass.getMethod(idName); 
     Method labelMethod = this.entityClass.getMethod(labelName); 
     for (E instance : entityAll) { 
      optionList.put((String)idMethod.invoke(instance),(String)labelMethod.invoke(instance)); 
     } 
    } catch (NoSuchMethodException ex){ 
     ... 
    } 
} 
+0

不起作用SysMyAbDao是抽象類和泛型類。用代碼編輯問題 – ciro

+0

@ciro:那麼你應該相應地修正你的'dao'參數的類型。我假定第一個泛型類型是上述變更代碼中'findAll()' - 方法返回的泛型類型。 –

+0

請用哪種方式? – ciro