【问题标题】:How to get parameter types using method name in java?如何在java中使用方法名获取参数类型?
【发布时间】:2016-10-05 05:40:59
【问题描述】:

说,我有课。

class Person{
    private int id;
    private String name;

    public void setId(int id){
        this.id = id;
    }

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

    public int getId(){
        this.id = id;
    }

    public String getName(){
        this.name = name;
    }
}

像这样,我有不止一个数据传输类。我希望有一个类,它将动态采用方法nameString.class)和参数valueObject.class),如下面的sn-p所示。

class Mapper{
    private Person person = new Person();
    private Method method = null;
    public void map(String methodName, Object parameterValue){
         // 1. Get the method using methodName.
         // 2. Get the method's parameter type.
         // 3. Type cast 'parameterValue' to parameter type.
         // 4. Call the method on 'person' object by passing type cast value
         //    from the 3-step(above).
    }
}

我试过搜索它。我得到了 Reflection API 的结果,如下面的 sn-p 所示。

Class<String> clz = String.class;
for (Method m : clz.getDeclaredMethods()) {
   System.err.println(m.getName());
   int paramCount = m.getParameterTypes().length;
   for (int i = 0;  i < paramCount;  i++) {
      System.err.println("  arg" + i);
   }
}

但是,这种方法不能满足我的需要。希望你能理解。

【问题讨论】:

  • Reflection API 将是要走的路。不过,这似乎是一个阴暗的设计。 map 的目的又是什么?
  • 为什么不能满足你的需求?
  • 你想在哪个类上动态调用方法?
  • 谢谢大家。我明白了。

标签: java methods reflection parameters


【解决方案1】:

如果您不想使用反射,我认为没有任何方法可以在 Java 中动态调用方法。 当您使用反射 API 时,请查看 Method 类中的以下方法。

public Object invoke(Object obj, Object... args)

很明显,您不需要强制转换传递给此方法的参数。

【讨论】:

  • 这样,调用者将不得不强制返回。
【解决方案2】:

你可以这样做:

class Person {
    public static final Map<String, BiConsumer<Person, ?>> methodMap = new HashMap<>();

    static {
        methodMap.put("setId", (BiConsumer<Person, Integer>) Person::setId);
        methodMap.put("setName", (BiConsumer<Person, String>) Person::setName);
    }

    private int id;
    private String name;

    public void setId(int id){
        this.id = id;
    }

    public void setName(String name){
        this.name = name;
    }
    ...
}
public <T> void map(String methodName, T parameterValue){
     ((BiConsumer<Person, ? super T>) Person.methodMap.get(methodName))
         .accept(person, parameterValue);
}

我假设你只想在你的 set 方法中使用它,因为你总是想传递一个参数。

【讨论】:

    【解决方案3】:

    如果你通过json,你可以在一行中完成,例如使用jackson:

    private static ObjectMapper mapper = new ObjectMapper(); // it's threadsafe
    

    然后在你的代码中:

    Person person = mapper.readValue(mapper.writeValueAsString(map), Person.class);
    

    您可以类似地使用 Gson 或您选择的其他 json 库。


    一些测试代码:

    import com.fasterxml.jackson.databind.ObjectMapper;
    
    Map<String, Object> map = new HashMap<>();
    map.put("id", 3);
    map.put("name", "bob");
    
    ObjectMapper mapper = new ObjectMapper();
    
    Person person = mapper.readValue(mapper.writeValueAsString(map), Person.class);
    
    System.out.println(person.getId());      
    System.out.println(person.getName());
    

    输出:

    3
    bob
    

    【讨论】:

    • 谢谢@Bohemian。我明白了。
    猜你喜欢
    • 2022-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-30
    • 1970-01-01
    • 1970-01-01
    • 2013-02-03
    相关资源
    最近更新 更多