2016-12-09 105 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