Java 如果方法采用基元类型,如何将字符串转换为setter函数?

Java 如果方法采用基元类型,如何将字符串转换为setter函数?,java,reflection,Java,Reflection,我试图为接受基元类型参数的类生成一个setter,但我得到一个异常,因为只允许使用非基元 为此,我将获取一个字符串,并按照POJO中函数的方式对其进行转换,但在描述参数类型(int)时,它将获取其包装类(Integer) 有谁能告诉我,是否有其他方法可以生成此方法,该方法适用于基本类型和非基本类型?如果您可以选择添加库。该库可用于处理bean和属性 在您的情况下,您可以: Method method = PropertyUtils.getReadMethod( new PropertyDescr

我试图为接受基元类型参数的类生成一个setter,但我得到一个异常,因为只允许使用非基元

为此,我将获取一个字符串,并按照POJO中函数的方式对其进行转换,但在描述参数类型(int)时,它将获取其包装类(Integer)


有谁能告诉我,是否有其他方法可以生成此方法,该方法适用于基本类型和非基本类型?

如果您可以选择添加库。该库可用于处理bean和属性

在您的情况下,您可以:

Method method = PropertyUtils.getReadMethod( new PropertyDescriptor(key, resultClass));

您尚未解释此方法的目的,但如果我理解正确,
value
是属性的示例值,您希望使用它来查找setter方法的参数类型

但是
value.getClass()
确实不适用于此,因为:

  • 它无法返回基元类型
  • 它可能返回setter方法的参数类型的子类
  • 如果
    为空,它将抛出一个NPE
  • 因此,有一些可能的替代方案:

  • 将setter作为lambda函数提供,而不是试图通过反射来侵入。这比使用反射更高效、更灵活

  • 如果必须使用反射,请为代码提供一个额外的
    Class
    变量,以便它知道setter方法的正确参数类型

  • 或者,任意选择,获取您看到的第一个具有setter名称的方法,无论其类型如何:

    Method method;
    String name = getSetMethod(key);
    for (Method m : resultClass.getClass().getMethods()) {
        if (m.getName().equals(name)) {
            method = m;
            break;
        }
    }
    
  • 有没有人能告诉我,是否有其他方法可以生成这个方法,它既适用于基本类型,也适用于非基本类型

    你不能那样做。您不能有一个适用于
    foo(int)
    foo(Integer)
    方法对象。因为那将是两种不同的方法

    编译器允许您使用
    foo(5)
    调用某些
    foo(Integer)
    ,原因是编译器使用装箱将5转换为整数对象,然后传递该对象

    记住:编译器在编译时决定调用哪个方法。如果有两个同名的方法具有不同的参数类型,那么这就是重载。。。并在编译时发生


    长话短说:要么您必须创建两个方法对象,要么您必须提供必要的代码,以便根据需要在基本引用和装箱引用类型之间装箱/取消装箱

    您将需要一些特殊的处理来将这些方法与原始参数与相应的装箱类型相匹配

    一种简单的方法可能就足够了,即在装箱类型和基元类型之间创建映射,并查找使用这两种类型的方法。这只是一个草图:

        Map<Class<?>, Class<?>> boxedToPrimitive = new HashMap<>();
        boxedToPrimitive.put(Integer.class, Integer.TYPE);
        boxedToPrimitive.put(Long.class, Long.TYPE);
        boxedToPrimitive.put(Boolean.class, Boolean.TYPE);
        ...
    
        String name = getSetMethod(key);
        Method method;
        try {
            method = target.getClass().getMethod(name, val.getClass());
        } catch (NoSuchMethodException missing) {
            Class<?> alt = boxedToPrimitive.get(val.getClass());
            if (alt == null) throw missing;
            method = target.getClass().getMethod(name, alt);
        }
        method.invoke(target, value);
    
    Map>boxedToPrimitive=newhashmap();
    boxedToPrimitive.put(Integer.class,Integer.TYPE);
    boxedToPrimitive.put(Long.class,Long.TYPE);
    boxedToPrimitive.put(Boolean.class,Boolean.TYPE);
    ...
    字符串名称=getSetMethod(键);
    方法;
    试一试{
    方法=target.getClass().getMethod(名称,val.getClass());
    }捕获(缺少NoSuchMethodException){
    Class alt=boxedToPrimitive.get(val.getClass());
    如果(alt==null)抛出丢失;
    方法=target.getClass().getMethod(名称,alt);
    }
    调用(目标、值);
    
    据我所知,这可以帮助您。您可以使用
    int.class
    来设置原语
    int
    等。
        Map<Class<?>, Class<?>> boxedToPrimitive = new HashMap<>();
        boxedToPrimitive.put(Integer.class, Integer.TYPE);
        boxedToPrimitive.put(Long.class, Long.TYPE);
        boxedToPrimitive.put(Boolean.class, Boolean.TYPE);
        ...
    
        String name = getSetMethod(key);
        Method method;
        try {
            method = target.getClass().getMethod(name, val.getClass());
        } catch (NoSuchMethodException missing) {
            Class<?> alt = boxedToPrimitive.get(val.getClass());
            if (alt == null) throw missing;
            method = target.getClass().getMethod(name, alt);
        }
        method.invoke(target, value);