java getMethod() 泛型类型

标签 java generics reflection

我想在泛型类型上使用反射

我有这门课

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;
    }
}

在我的 Controller 中

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

但我明白了

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

java 搜索泛型类型 e,而不是我在构造函数中使用的类型

我希望对我在 Controller 中使用的类型进行搜索。 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;
    }
}

最佳答案

您有一个额外的getClass()在这一行中:

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

事实上,您正在调用 getClass()关于Class<E>目的。并作为 Class<E> 的类(class)不是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){
        ...
    }
}

关于java getMethod() 泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41069450/

相关文章:

java - 在java反射中将Field.get()返回的Object转换为String[]

c# - 无法捕获的异常,第 2 部分

java - uiautomator 多次断言

c# - 如何让泛型处理需要仔细转换的返回值?

java - Java Generics 和 Apache Olingo 4 的编译错误

java - Java 中的嵌套泛型

haskell - 反射是否有不连贯的风险?

Java IntToBinary 应用程序 : Exception in thread "main" java. lang.IllegalStateException:扫描仪已关闭

java - 动态填充 thymeleaf 中的列表

java - 如何将单个实现绑定(bind)到 Guice 中的多个通用接口(interface)?