How to pass method name dynamically in java

2020-06-17 06:41发布

问题:

I have an Class like as follows

public class Test
{
     private Long id;
     private Long locationId;
     private Long anotherId;

    public Long getId() {
    return id;
}


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


public Long getLocationId() {
    return locationId;
}


public void setLocationId(Long locationId) {
    this.locationId = locationId;
}


public Long getAnotherId() {
    return anotherId;
}


public void setAnotherId(Long anotherId) {
    this.anotherId = anotherId;
}
}

I have used following methods in various places to find the matched object by using id,locationId or anotherId

public Test getMatchedObject(List<Test> list,Long id )
{

          for(Test vo : list)
                if(vo.getId() != null && vo.getId().longValue() == id.longValue())
                return vo;
}

public Test getMatchedLocationVO(List<Test> list,Long locationId )
{

          for(Test vo : list)
                if(vo.getLocationId() != null && vo.getLocationId().longValue() == locationId.longValue())
                return vo;
}

public Test getMatchedAnotherVO(List<Test> list,Long anotherId )
{

          for(Test vo : list)
                if(vo.getAnotherId() != null && vo.getAnotherId().longValue() == anotherId.longValue())
                return vo;
}

I used different method for each parameter to find out the object.Is there any way i can pass method name dynamically?

Thanks in advance...

回答1:

You need to use reflection to do this.

import java.lang.reflect.*;

Method method = obj.getClass().getMethod(methodName);

then invoke it with method.invoke(obj, arg1, arg2);

This is somewhat similar to the way call works in javascript (if you're familiar with that), except instead of passing the context, you're passing the object and a reference to it's method.



回答2:

You can do this with reflection, but it's probably not the best solution to your original problem as reflection is meant for use by programming tools. You should look into using other tools, like polymorphism and inheritence, that can provide similar functionality.



回答3:

Although you are calling methods dynamically and it seems like reflection, but as far as I see, you are calling accessors and nested accessors, which leads to use Java Introspection API.

It supports Java Bean API, and accessors/mutators and nested accessors/mutators easily.

There are some other libraries which simplify this too, such as Apache BeanUtils, and BeanWrapper class by Spring.



回答4:

Possible solution using interface.. Hope you get the idea.. Code doesn't necessarily compiles. Apologies for formatting as this is entered only in iPad.

public interface IdMatcher{
  Long id;
  public boolean matches(Test obj);
}

Concrete class:

public class LocationIdMatcher implements IdMatcher() {
  public LocationIdMatcher(id) {
  this.id = id;
}
public boolean matches(Test obj) {
   if (obj.getLocationId() == this.id)
    return true;
   }
}

getMatchedVO updated:

public Test getMatchedVO(List<Test> list, IdMatcher idMatcher) {
  for(Test vo: list) {
   if(idMatcher.matches(vo) {
     return vo;
   }
  }
  return null;
}

Usage:

Test vo = getMatchedVO(list, new LocationIdMatcher(locationId));


回答5:

By using Reflection API you can do it see this example